10

我正在使用 Spring MVC 3.2.2

我已经定义了一个像这样的自定义 HandlerMethodArgumentResolver 类

public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {

  public CurrentUserArgumentResolver() {
    System.out.println("Ready");
  }

  @Override
  public boolean supportsParameter(MethodParameter parameter) {
    return parameter.hasParameterAnnotation(CurrentUser.class);
  }

  @Override
  public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

      Principal principal = webRequest.getUserPrincipal();
      System.out.println("*** Principal ***: " + principal);
      return principal;
  }
}

并将以下内容添加到我的 app-servlet.xml

<mvc:annotation-driven>
  <mvc:argument-resolvers>
    <beans:bean class="my.package.CurrentUserArgumentResolver" lazy-init="false"/>
  </mvc:argument-resolvers>
</mvc:annotation-driven>

并为 CurrentUser 创建了一个注释

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {

}

当我启动应用程序时,构造类,因为我可以看到日志消息“就绪”,但是当我这样注释控制器方法时解析器不会执行(在具有 @Controller 注释的类中)

@RequestMapping(method = RequestMethod.POST, value = "/update")
public ModelAndView update(@RequestParam MultipartFile background, @CurrentUser Principal principal) {
 ...
}

如果我在 CurrentUserArgumentResolver 类中的任一方法上设置断点,都不起作用。所以不确定我错过了什么?

4

3 回答 3

19

如果有人想要将自定义处理程序优先于 spring 添加的默认处理程序,这是一个为我做的片段,我在@Configuration文件中执行此操作

private @Inject RequestMappingHandlerAdapter adapter;

@PostConstruct
public void prioritizeCustomArgumentMethodHandlers () {
  List<HandlerMethodArgumentResolver> argumentResolvers = 
      new ArrayList<> (adapter.getArgumentResolvers ());
  List<HandlerMethodArgumentResolver> customResolvers = 
      adapter.getCustomArgumentResolvers ();
  argumentResolvers.removeAll (customResolvers);
  argumentResolvers.addAll (0, customResolvers);
  adapter.setArgumentResolvers (argumentResolvers);
}
于 2013-11-07T21:58:58.573 回答
3

好的,我发现 Spring 已经在上面的示例中解析了 Principal 对象,因此我的参数解析器没有启动。我一直很懒,并将 @CurrentUser 注释添加到现有参数中。

所以我改变了我的例子

@RequestMapping(method = RequestMethod.POST, value = "/update")
public ModelAndView update(@RequestParam MultipartFile background, @CurrentUser Principal principal) {
  ...
}

使用我的用户模型类

@RequestMapping(method = RequestMethod.POST, value = "/update")
public ModelAndView update(@RequestParam MultipartFile background, @CurrentUser User user) {
  ...
}

现在它可以工作了!

于 2013-06-29T13:05:45.207 回答
0

我使用该属性customArgumentResolvers来加载 bean,如下所示:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8</value>
                            <value>text/plain;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
         <property name="customArgumentResolvers">
         <list>
             <bean id="MyTestMethodArgumentResolver" class="com.gst.authorization.resolvers.MyTestMethodArgumentResolver"></bean>           
             <bean id="currentUserMethodArgumentResolver" class="com.gst.authorization.resolvers.CurrentUserMethodArgumentResolver">
                            <property name="userModelClass" value="com.gst.model.appuser.AppUser" />
                    <property name="userModelRepository" ref="userRepository" />
                </bean>
         </list>         
         </property>
    </bean> 
    <mvc:annotation-driven />
于 2016-08-22T06:55:58.237 回答