java系统开发的时候,相信大家都需要获取当前登录用户,用来记录操作员、格式化日期参数、操作线程信息、分页配置信息、将数据信息驼峰与数据库命名方式进行转换等。
针对这种参数解析,我们有两种方案可采用: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 {@Overridepublic Object resolveArgument(MethodParameter param, NativeWebRequest request) throws Exception {// param是否可赋值Account参数; ???????if(Account.class.isAssignableFrom(param.getParameterType())) {return new Account();}return null;}//参数是否包含某注解RequestOperationif (methodParameter.hasParameterAnnotation(RequestOperation.class)) {return OperationContextHolder.get();}return WebArgumentResolver.UNRESOLVED;
}
问题是 AccountArgumentResolver 可以执行,但下面的 DeviceTypeWebArgumentResolver 有时候无法执行,后来查阅了资料发现,在resolveArgument方法中当对象的类型不是指定的类型的时候,必须返回 WebArgumentResolver.UNRESOLVED而不是null,否则下一个参数解析器无法执行。
第二个问题:参数解析器在过滤器之前执行
如果参数解析器是通过实现WebArgumentResolver接口创建的话,其中的resolveArgument方法会在 <mvc:interceptors>...</mvc:interceptors> 中定义的过滤器之后执行。
Spring 3.1之后增加一个HandlerMethodArgumentResolver接口,该接口的方法是在过滤器之后执行的,并且resolveArgument方法可以返回null,不会造成上面的问题。
因此,后面可以使用 HandlerMethodArgumentResolver 完全替代 WebArgumentResolver 接口。