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); }