mockRequest构建request请求
private static HttpServletRequest mockRequest(){MockHttpServletRequest request = new MockHttpServletRequest();request.setParameter("name1","zhangsan");request.setParameter("name2","lisi");request.setParameter("age","18");return new StandardServletMultipartResolver().resolveMultipart(request);
}
定义controller
static class Controller{public void test(@RequestParam("name1") String name1,String name2,@RequestParam("age") int age,@RequestParam(value = "home",defaultValue = "${JAVA_HOME}") String home1){}
}
解析过程
public static void main(String[] args) throws Exception {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();HttpServletRequest multiRequest = mockRequest();// 控制器方法封装为 handlerMethodHandlerMethod handlerMethod = new HandlerMethod(new Controller(),Controller.class.getMethod("test", String.class, String.class, int.class,String.class));// 数据绑定工厂DefaultDataBinderFactory factory = new DefaultDataBinderFactory(null);// ModelAndViewContainer 存储Model结果.ModelAndViewContainer container = new ModelAndViewContainer();// 拿到当前控制器方法得参数信息for (MethodParameter methodParameter : handlerMethod.getMethodParameters()) {// 创建解析器对象 -> 是在HandlerMethodAdapter中RequestParamMethodArgumentResolver resolver = new RequestParamMethodArgumentResolver(beanFactory,false);// 拿到当前的参数methodParameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());// 当前解析器支持这个参数进行处理 如果标注了@RequestParam注解从请求参数里找到对应的信息if (resolver.supportsParameter(methodParameter)) {Object v = resolver.resolveArgument(methodParameter,container,new ServletWebRequest(multiRequest),factory);System.out.println("[" + methodParameter.getParameterIndex() + "]" + methodParameter.getParameterType().getSimpleName() + " " + methodParameter.getParameterName() + "->" + v);}else{System.out.println("[" + methodParameter.getParameterIndex() + "]" + methodParameter.getParameterType().getSimpleName() + " " + methodParameter.getParameterName());}}
}
通过handlerMethod.getMethodParameters拿到方法对应的全部的参数,然后对参数内容进行解析,
RequestParamMethodArgumentResolver用来解析@RequestParam注解;
首先通过supportsParameter看当前参数是否满足解析要求;
如果满足则进行参数解析赋值;resolver.resolveArgument
使用组合解析器进行优化
每个参数的解析需要用到不同的参数解析器,那么我们可以定义一个组合的参数解析器,进行解析时逐个去解析我们组合解析器中参数解析找到满足的一个然后进行解析。
// 创建解析器组合对象内部会循环找到当前参数满足的解析器进行解析
HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite();
composite.addResolvers(new RequestParamMethodArgumentResolver(beanFactory,false), // 解析@RequestParamnew PathVariableMethodArgumentResolver(), // 解析@PathVariablenew RequestHeaderMethodArgumentResolver(beanFactory), // 解析 @RequestHeadernew ServletCookieValueMethodArgumentResolver(beanFactory), // 解析@Cookie()new ExpressionValueMethodArgumentResolver(beanFactory) // 解析@Value
);// 拿到当前的参数
methodParameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
// 当前解析器支持这个参数进行处理 如果标注了@RequestParam注解从请求参数里找到对应的信息
if (composite.supportsParameter(methodParameter)) {Object v = composite.resolveArgument(methodParameter,container,new ServletWebRequest(multiRequest),factory);System.out.println("[" + methodParameter.getParameterIndex() + "]" + methodParameter.getParameterType().getSimpleName() + " " + methodParameter.getParameterName() + "->" + v);
}else{System.out.println("[" + methodParameter.getParameterIndex() + "]" + methodParameter.getParameterType().getSimpleName() + " " + methodParameter.getParameterName());
}