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同理,对返回参数做修改

  • 同时实现了HandlerMethodReturnValueHandlerHandlerMethodArgumentResolver的类是RequestResponseBodyMethodProcessor,它做了什么呢?

原来我们日常使用的@RequestBody,@ResponseBody就是通过RequestResponseBodyMethodProcessor来处理的,通过HttpMessageConverter处理读入与写出的请求体~


SpringMVC中HandlerMethodArgumentResolver的作用
https://www.blaaair.com/archives/springmvc-zhong-handlermethodargumentresolver-de-zuo-yong
作者
Glo6f
发布于
2024年04月21日
许可协议