在上一篇文章中我们分析了SpringMVC对简单对象和@RequestParam注解的解析过程,这一章中我们继续分析其他形式的参数解析过程。
下面来看一下我们的第一个请求:http://localhost:8086/allRequestFormat/requestAndResponseRequest?userName=zhangsan
对应的后台处理代码是:
我们的请求处理方法中的两个参数是HttpServletRequest和HttpServletResponse类型,那么SpringMVC在调用requestAndResponseRequest这个方法的时候是怎么解析到这两个参数的值的呢?我们先看HttpServletRequest这个参数,这个参数是ServletRequestMethodArgumentResolver这个类来解析的。在上一篇文章中,我们知道通过调用argumentResolvers.supportsParameter这个方法来判断HandlerMethodArgumentResolver的实现类是否支持对应的参数的解析,和resolveArgument方法来实现真正的参数解析。
所以我们先看一下ServletRequestMethodArgumentResolver这个类中的supportsParameter这个方法的内容:
从上面的代码中我们可以看到如果参数类型为WebRequest类型、ServletRequest类型、MultipartRequest类型、HttpSession类型、Principal类型、InputStream类型、Reader类型或者HttpMethod类型、Locale类型、TimeZone类型、ZoneId类型则使用这个参数解析器进行参数的解析工作。
下面我们在看一下ServletRequestMethodArgumentResolver是怎么进行参数解析工作的:
从上面的代码中我们发现最主要的是NativeWebRequest这个对象,我们可以从这个对象中获取到HttpServletRequest,从HttpServletRequest中获取一系列的其他对象的值。我们可以看一下NativeWebRequest这个对象的值是怎么创建的。在RequestMappingHandlerAdapter#invokeHandlerMethod中有这样一段代码:
在ServletWebRequest这个对象中持有request和response这两个对象的引用。ServletWebRequest的UML类图关系如下:

所以resolveArgument中的NativeWebRequest其实是ServletWebRequest这个对象。
上面分析完了HttpServletRequest,我们还有一个参数类型是HttpServletResponse,那么这个HttpServletResponse这个参数是谁解析的呢?是ServletResponseMethodArgumentResolver来解析的。我们看一下它的supportsParameter方法的实现:
ServletResponseMethodArgumentResolver解析的参数类型是:ServletResponse类型、OutputStream类型和Writer类型。我们再看下一resolveArgument方法中对参数解析的实现:
这个参数的解析过程和ServletRequestMethodArgumentResolver中对象参数的解析过程如出一辙。我们对HttpServletRequest和HttpServletResponse参数的解析就先到这里了。