21. Servlet API参数解析原理
例如下面的HttpServletRequest request这个参数。
@GetMapping("/goto")
public String Goto(HttpServletRequest request){
request.setAttribute("msg","hah");
request.setAttribute("mn","xsa");
return "forward:/sucess";
}
@ResponseBody
@GetMapping("/sucess")
public Map<String,Object> sucess(HttpServletRequest request,
@RequestAttribute("msg") String msg,
@RequestAttribute("mn") String mn){
Map<String, Object> map=new HashMap<>();
Object msg1 = request.getAttribute("msg");
map.put("mag",msg1);
map.put("mn",mn);
return map;
}
其中的过程和上一篇的注解参数的原理是一样的,只不过在查找支持的解析该参数的解析器的类型是不一样的。
进入到上面的代码,可以看出来下面的这些参数类型上面的解析器都是可以解析的。都是一些servlet api的参数。
public boolean supportsParameter(MethodParameter parameter) {
Class<?> paramType = parameter.getParameterType();
return WebRequest.class.isAssignableFrom(paramType) ||
ServletRequest.class.isAssignableFrom(paramType) ||
MultipartRequest.class.isAssignableFrom(paramType) ||
HttpSession.class.isAssignableFrom(paramType) ||
pushBuilder != null &&
pushBuilder.isAssignableFrom(paramType) ||
Principal.class.isAssignableFrom(paramType) &&
!parameter.hasParameterAnnotations() ||
InputStream.class.isAssignableFrom(paramType) ||
Reader.class.isAssignableFrom(paramType) ||
HttpMethod.class == paramType || Locale.class ==
paramType || TimeZone.class == paramType ||
ZoneId.class == paramType;
}
然后开始解析。
第一句代码是得到刚才得到的解析器,然后判断一下,然后调用解析器的方法进行解析,是下面的这段代码。
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
Class<?> paramType = parameter.getParameterType();
if (WebRequest.class.isAssignableFrom(paramType)) {
if (!paramType.isInstance(webRequest)) {
throw new IllegalStateException("Current request is not of type [" + paramType.getName() + "]: " + webRequest);
} else {
return webRequest;
}
} else {
return
!ServletRequest.class.isAssignableFrom(paramType) &&
!MultipartRequest.class.isAssignableFrom(paramType) ?
this.resolveArgument(paramType,
(HttpServletRequest)this.resolveNativeRequest(webRequest, HttpServletRequest.class)) :
this.resolveNativeRequest(webRequest, paramType);
}
}
然后进行解析。