在Spring MVC的Controller的方法中,可以直接使用 Model
这样的参数,这是因为在调用Controller方法之前已经对指定的参数进行预处理了,Spring MVC分别提供了WebArgumentResolver 和HandlerMethodArgumentResolver接口,具体的用法很容易查到,这里说两个遇到的问题。
第一个问题:在配置文件中自定义的argument只有第一个有效,后面的参数都无效。
相关的配置信息如下:
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.javatang.example.biz.interceptor.AccountArgumentResolver" />
<bean class="com.javatang.example.biz.interceptor.DeviceTypeWebArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
AccountArgumentResolver.java文件内容如下:
public class AccountArgumentResolver implements WebArgumentResolver {
@Override
public Object resolveArgument(MethodParameter param, NativeWebRequest request) throws Exception {
if(Account.class.isAssignableFrom(param.getParameterType())) {
return new Account();
}
return null;
}
}
问题是 AccountArgumentResolver
可以执行,但下面的 DeviceTypeWebArgumentResolver
有时候无法执行,后来查阅了资料发现,在resolveArgument方法中当对象的类型不是指定的类型的时候,必须返回 WebArgumentResolver.UNRESOLVED而不是null,否则下一个参数解析器无法执行。
第二个问题:参数解析器在过滤器之前执行
如果参数解析器是通过实现WebArgumentResolver接口创建的话,其中的resolveArgument
方法会在 <mvc:interceptors>...</mvc:interceptors>
中定义的过滤器之后执行。
Spring 3.1之后增加一个HandlerMethodArgumentResolver接口,该接口的方法是在过滤器之后执行的,并且resolveArgument
方法可以返回null,不会造成上面的问题。
因此,后面可以使用 HandlerMethodArgumentResolver
完全替代 WebArgumentResolver
接口。
参考资料:
Spring mvc - implementation of WebArgumentResolver
spring mvc WebArgumentResolver不生效
Spring Web MVC 3.1.1 argument resolver called before interceptor