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)的情况。

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<Object> objects) { 


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

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

[1,2,3]

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

RequestHeaderMethodArgumentResolver

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

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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值