SpringMVC中HandlerMethodArgumentResolver的作用
SpringMVC中HandlerMethodArgumentResolver的作用
1.前言
有的时候,我们可能需要对一类controller层的参数进行过滤或者加工,但是我们并不想每次都进行相关的操作.所以此时我们的
HandlerMethodArgumentResolver
就派上用场了!
2.例子
下面我们用一个获取当前用户的例子感受一下
public class UserContextArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
boolean isUserContext = UserContext.class.isAssignableFrom(parameter.getParameter().getType());
return isUserContext;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String ip = IpUtils.getIpAddr(webRequest.getNativeRequest(HttpServletRequest.class));
String header = webRequest.getHeader("Authentication");
if (UserContext.class.isAssignableFrom(parameter.getParameter().getType())) {
return userContext(header, ip);
}
return null;
}
private UserContext userContext(String header, String ip) {
if (StringUtils.isBlank(header)) {
return new UserContext();
}
// 拿取数据 ,可能是数据库中的也可能是缓存中的,anywhere~
Object data = ...
if (data == null) {
return new UserContext();
}
UserContext userContext = new UserContext();
userContext.setUserId(baseUserQueryBO.getBuId());
userContext.setAccount(baseUserQueryBO.getAccount());
userContext.setUserCode(baseUserQueryBO.getBuCode());
userContext.setUserName(baseUserQueryBO.getBuName());
userContext.setRequestIpHost(ip);
return userContext;
}
}
-
自定义类继承
HandlerMethodArgumentResolver
,实现 :boolean supportsParameter(MethodParameter parameter)
:接收支持的类型,如果返回true ,就会进入Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory)
方法Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory)
:返回值代表被拦截参数,通过这个方法就会注入相关的属性.
3.注入方式
3.1 传统SpringMVC
在springmvc.xml
中增加 :
<!--用户信息自动注入 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="customArgumentResolvers">
<list>
<bean class="com.blaaair.base.utils.usercontext.UserContextArgumentResolver" />
</list>
</property>
</bean>
3.2 springboot
直接在启动类上增加 :
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new UserContextArgumentResolver());
}
还有一种是注入一个bean
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new UserContextArgumentResolver());
}
4.扩展
此处只是改变了mvc的方法参数,当然了返回值什么的巴拉巴拉的都是可修改的
HandlerMethodReturnValueHandler
public boolean supportsReturnType(MethodParameter returnType) {
return returnType.getMethodAnnotation(ResponseBody.class) != null;
}
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
throws IOException, HttpMediaTypeNotAcceptableException {
mavContainer.setRequestHandled(true);
if (returnValue != null) {
writeWithMessageConverters(returnValue, returnType, webRequest);
}
}
HandlerMethodReturnValueHandler
的方法与HandlerMethodArgumentResolver
同理,对返回参数做修改
- 同时实现了
HandlerMethodReturnValueHandler
与HandlerMethodArgumentResolver
的类是RequestResponseBodyMethodProcessor
,它做了什么呢?
原来我们日常使用的
@RequestBody
,@ResponseBody
就是通过RequestResponseBodyMethodProcessor
来处理的,通过HttpMessageConverter
处理读入与写出的请求体~
SpringMVC中HandlerMethodArgumentResolver的作用
https://www.blaaair.com/archives/springmvc-zhong-handlermethodargumentresolver-de-zuo-yong