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

然后进行解析。

posted @ 2022-08-08 10:47  随遇而安==  阅读(33)  评论(0编辑  收藏  举报