HandlerMethodArgumentResolver的抽象實現AbstractNamedValueMethodArgumentResolver下的子类

 Annotation-based argument resolution 部分2 

 

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultArgumentResolvers 中 

// Annotation-based argument resolution
@Value                        ExpressionValueMethodArgumentResolver 
@MatrixVariable               MatrixVariableMethodArgumentResolver     ,MatrixVariableMapMethodArgumentResolver
@PathVariable                 PathVariableMethodArgumentResolver       ,PathVariableMapMethodArgumentResolver
@RequestAttribute             RequestAttributeMethodArgumentResolver
@RequestHeader                RequestHeaderMethodArgumentResolver      ,RequestHeaderMapMethodArgumentResolver
@RequestParam                 RequestParamMethodArgumentResolver       ,RequestParamMapMethodArgumentResolver
@CookieValue                  ServletCookieValueMethodArgumentResolver
@SessionAttribute             SessionAttributeMethodArgumentResolver
@RequestPart                  RequestPartMethodArgumentResolver
@ModelAttribute               ServletModelAttributeMethodProcessor
@RequestBody,@ResponseBody    RequestResponseBodyMethodProcessor

 以上总计15种默认基于注解的参数解析器。使用12种注解。

 

 

ExpressionValueMethodArgumentResolver
MatrixVariableMethodArgumentResolver
PathVariableMethodArgumentResolver
RequestAttributeMethodArgumentResolver
RequestHeaderMethodArgumentResolver
RequestParamMethodArgumentResolver
ServletCookieValueMethodArgumentResolver
SessionAttributeMethodArgumentResolver

 

 

 

 

ExpressionValueMethodArgumentResolver、
    @Value
        value
        
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(Value.class);
    }
    直接在参数上注解@Value("${xxxx}")可以直接使用Spring上线文中的值,最普遍的用法是,获取配置文件中配置的值。
    
MatrixVariableMethodArgumentResolver(觉得叫做 MatrixPathVariableMethodArgumentResolver更合适,与PathVariableMethodArgumentResolver呼应,仅解析为/owners/{ownerId}/pets/{petId}该格式url)

    使用参考:https://www.cnblogs.com/hfultrastrong/p/11491391.html

    @MatrixVariable
        value
        name
        pathVar
        required
        defaultValue

    // .参数必须存在@MatrixVariable注解
        或者
    // .如果参数类型为Map.class.isAssignableFrom 则@MatrixVariable参数中必须存在名称
    public boolean supportsParameter(MethodParameter parameter) {
        if (!parameter.hasParameterAnnotation(MatrixVariable.class)) {
            return false;
        }
        if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) {
            MatrixVariable matrixVariable = parameter.getParameterAnnotation(MatrixVariable.class);
            return (matrixVariable != null && StringUtils.hasText(matrixVariable.name()));
        }
        return true;
    }
    
    ---
    
    请求路径是这种类型 才能解析到参数
    // GET /owners/42;q=11/pets/21;q=22  
    @RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET)  
    
    ---
    
    通过该方法构造matrix参数:org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#extractMatrixVariables



PathVariableMethodArgumentResolver
    使用限定同上 MatrixVariableMethodArgumentResolver
    public boolean supportsParameter(MethodParameter parameter) {
        if (!parameter.hasParameterAnnotation(PathVariable.class)) {
            return false;
        }
        if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) {
            PathVariable pathVariable = parameter.getParameterAnnotation(PathVariable.class);
            return (pathVariable != null && StringUtils.hasText(pathVariable.value()));
        }
        return true;
    }


    接收参数必须加 @PathVariable 才能解析到参数值
    @RequestMapping("tcashier/login/{abc}")
    public String tcashier(@PathVariable(name = "abc") String aaa) {
        return "tcashier/login";
    }
    







RequestAttributeMethodArgumentResolver
    
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestAttribute.class);
    }

    必须存在 @RequestAttribute注解
    才能通过以下方法取到值
    request.getAttribute(name, RequestAttributes.SCOPE_REQUEST);


RequestHeaderMethodArgumentResolver
    有@MethodParameter 并且参数类型不能为Map
    public boolean supportsParameter(MethodParameter parameter) {
        return (parameter.hasParameterAnnotation(RequestHeader.class) &&
                !Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType()));
    }
    
    通过以下方法获取参数值
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
        String[] headerValues = request.getHeaderValues(name);
        if (headerValues != null) {
            return (headerValues.length == 1 ? headerValues[0] : headerValues);
        }
        else {
            return null;
        }
    }



RequestParamMethodArgumentResolver

    // 存在@RequestParam注解
    // 或者
    // 参数类型为Map.class.isAssignableFrom并且存在@RequestParam注解,且@RequestParam.name存在值
    // 或者
    // 是文件类型 MultipartResolutionDelegate.isMultipartArgument(parameter)
    // 或者
    // this.useDefaultResolution 为 true,并且参数类型为简单类型 BeanUtils.isSimpleProperty
    public boolean supportsParameter(MethodParameter parameter) {
        if (parameter.hasParameterAnnotation(RequestParam.class)) {
            if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) {
                RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class);
                return (requestParam != null && StringUtils.hasText(requestParam.name()));
            }
            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;
            }
        }
    }    
    
    
    主要解析两种参数,一种是请求参数,另一种是文件类型
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
        HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);

        if (servletRequest != null) {
            Object mpArg = MultipartResolutionDelegate.resolveMultipartArgument(name, parameter, servletRequest);
            if (mpArg != MultipartResolutionDelegate.UNRESOLVABLE) {
                return mpArg;
            }
        }

        Object arg = null;
        MultipartRequest multipartRequest = request.getNativeRequest(MultipartRequest.class);
        if (multipartRequest != null) {
            List<MultipartFile> files = multipartRequest.getFiles(name);
            if (!files.isEmpty()) {
                arg = (files.size() == 1 ? files.get(0) : files);
            }
        }
        if (arg == null) {
            String[] paramValues = request.getParameterValues(name);
            if (paramValues != null) {
                arg = (paramValues.length == 1 ? paramValues[0] : paramValues);
            }
        }
        return arg;
    }






ServletCookieValueMethodArgumentResolver
    
    在父类中存在如下判断
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(CookieValue.class);
    }
    只能处理@CoolieValue注解的参数
    ----
    
    通过以下方法得到参数值
    protected Object resolveName(String cookieName, MethodParameter parameter,
            NativeWebRequest webRequest) throws Exception {

        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        Assert.state(servletRequest != null, "No HttpServletRequest");

        Cookie cookieValue = WebUtils.getCookie(servletRequest, cookieName);
        if (Cookie.class.isAssignableFrom(parameter.getNestedParameterType())) {
            return cookieValue;
        }
        else if (cookieValue != null) {
            return this.urlPathHelper.decodeRequestString(servletRequest, cookieValue.getValue());
        }
        else {
            return null;
        }
    }


SessionAttributeMethodArgumentResolver
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(SessionAttribute.class);
    }
    使用@SessionAttribute注解获取session值

    ----
    
    使用如下方法获取参数值
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) {
        return request.getAttribute(name, RequestAttributes.SCOPE_SESSION);
    }

  































 

posted @ 2019-12-18 18:10  GordonDicaprio  阅读(428)  评论(0编辑  收藏