作用
HandlerMethodArgumentResolver 是请求参数解析器,不管你是要获取Cookie中的值,Header中的值,JSON格式的数据,URI中的值,还是请求体中的数据,Spring都提供了相对应的参数解析器来提取参数。Spring默认提供了26中参数解析器,比如我们最常用的参数注解 @RequestParam 就是由 RequestParamMethodArgumentResolver 解析的,PathVariableMethodArgumentResolver 用来解析 @PathVariable 注解。
执行时机
参考SpringMVC源码解析“解析请求参数值”部分。
应用
这里我们来自定义一个参数解析器,实现为用户id自动赋值。
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/find")
public String find(@UserId String userId) {
System.out.println(userId);
return "success";
}
}
自定义一个注解@UserId,作用在userId参数上
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserId {
}
然后自定义一个参数解析器,实现 HandlerMethodArgumentResolver 接口
public class UserIdMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 当参数上有@UserId时才使用该解析器解析
return parameter.hasParameterAnnotation(UserId.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 假设从session中获取到了userId
Object userId = webRequest.getAttribute("userId", NativeWebRequest.SCOPE_SESSION);
if (userId == null) {
throw new RuntimeException("非法调用");
}
return userId;
}
}
最终我们需要将自定义的参数解析器注入到 RequestMappingHandlerAdapter 适配器的 customArgumentResolvers 的集合属性中。但是该适配器一般是由 <mvc:annotation-driven /> 标签帮我们自动注入的,所以需要在该标签里添加上自己的参数解析器
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.huangsz.springmvcdemo.LoginRequiredArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>