HandlerMethodArgumentResolver-处理器参数解析

HandlerMethodArgumentResolver

springmvc中仅仅加个@Controller @RequestMaping等注解就可以将普通的java方法成为一个Handler处理器。spring通过HandlerMethodArgumentResolver来解析handler处理器参数问题。

HandlerMethodArgumentResolver 接口

boolean supportsParameter(MethodParameter parameter); 

Object resolveArgument(MethodParameter parameter......

PS:MethodParamter 方法参数信息的封装类,可以通过它获取方法上参数的名称,类型,注解,所在的方法等等

Method showParam = DemoUserSon.class.getMethod("showParam", String.class, Integer.class);
Parameter[] parameters = showParam.getParameters();
//识别方法的参数名字 基于ASM
DefaultParameterNameDiscoverer defaultParameterNameDiscoverer = new DefaultParameterNameDiscoverer();
for (int i = 0; i < parameters.length; i++) {
    MethodParameter methodParameter = new MethodParameter(showParam,i);
    methodParameter.initParameterNameDiscovery(defaultParameterNameDiscoverer);
    System.out.println("参数类型:"+methodParameter.getParameterType());
    System.out.println("参数名称"+methodParameter.getParameterName());
    Arrays.stream(methodParameter.getParameterAnnotations()).forEach(x -> System.out.println("参数上的注解:"+x.annotationType()));
}
参数类型:class java.lang.String
参数名称name
参数上的注解:interface javax.validation.constraints.NotNull
参数类型:class java.lang.Integer
参数名称age

AbstractNamedValueMethodArgumentResolver

该类主要是用来处理解析Request parameters, request headers, and path variables 的命名值,比如get请求  ?id=110,那么就从id获取这个id值100。
具体都是由子类来实现:为方法参数获取命名值、解析这些命名值到方法参数、适当处理如果参数值没有的(required)的情况。

HandlerMethodArgumentResolver-处理器参数解析_第1张图片

RequestParamMethodArgumentResolver

这个是最常用的解析器,处理一下三种情况:RequestParam 、RequestPart(MultipartFile,javax.servlet.http.Part)、以及默认兜底处理简单属性。

public boolean supportsParameter(MethodParameter parameter) {
   if (parameter.hasParameterAnnotation(RequestParam.class)) {
      if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) {
         String paramName = parameter.getParameterAnnotation(RequestParam.class).name();
         return StringUtils.hasText(paramName);
      }
      else {
         return true;
      }
   }
   else {
      if (parameter.hasParameterAnnotation(RequestPart.class)) {
         return false;
      }
      parameter = parameter.nestedIfOptional();
      if (MultipartResolutionDelegate.isMultipartArgument(parameter)) {
         return true;
      }
      else if (this.useDefaultResolution) {
         return BeanUtils.isSimpleProperty(parameter.getNestedParameterType());
      }
      else {
         return false;
      }
   }
}
public static boolean isSimpleValueType(Class clazz) {
   return (ClassUtils.isPrimitiveOrWrapper(clazz) || clazz.isEnum() ||
         CharSequence.class.isAssignableFrom(clazz) ||
         Number.class.isAssignableFrom(clazz) ||
         Date.class.isAssignableFrom(clazz) ||
         URI.class == clazz || URL.class == clazz ||
         Locale.class == clazz || Class.class == clazz);
}

关于请求数组传参问题

@ResponseBody
    @GetMapping("/test")
    public Object test(@RequestParam List objects) { 


        System.out.println(objects);
        return objects;
    }

请求URL:/test/?objects=1,2,3。控制台打印:

[1,2,3]

 传参可以是@RequestParam List objects   或者@RequestParamObject[] objects , 对于List,@RequestParam必须存在,因为不是简单类型 ,但是String[]objects这样是可以不用注解的,因为它是简单类型,可以走兜底的默认解析RequestParamMethodArgumentResolver。

RequestHeaderMethodArgumentResolver

@ResponseBody
    @GetMapping("/test")
    public Object test(@RequestHeader("Accept-Encoding") String encoding,
                       @RequestHeader("Accept-Encoding") List encodingList) {
        System.out.println(encoding);
        System.out.println(encodingList);
        return encoding;
    }
逗号隔开,装转成了数组或集合,注解指定的value值是可以不区分大小写的
gzip, deflate, br
[gzip, deflate, br]

在这里插入图片描述
类似的像:ServletCookieValueMethodArgumentResolver 的 @CookieValue("JSESSIONID") String cookieValue

 

你可能感兴趣的:(springmvc,spring,java)