最近很多交互都要处理原生的HttpServletRequest和HttpServletResponse。从HttpServletRequest读取body数据,封装成某种数据结构;将数据写入HttpServletResponse并响应。传统的写法很不优雅。今天给大家介绍一种比较优雅的方式。HttpMessageConverterHttpMessageConverter是Spring框架提供的消息转换器模型,HTTP请求和响应之间转换的策略接口。它可以读取输入消息HttpInputMessage;它还可以编写输出消息HttpOutputMessage。HttpMessageConverterSpringMVC的消息转换就是通过这个接口的实现来完成的。HttpMessageConverter的实现有很多种:HttpMessageConverter的常见实现通常在SpringMVC中处理Form表单提交、JSON、XML、字符串,甚至Protobuf都是通过HttpMessageConverter的实现来完成的。前端传给后端的body参数,以及后端返回给前端的数据,都是通过这个接口完成转换的。在SpringIoC(SpringMVC环境)中,还有一个存放HttpMessageConverters的容器HttpMessageConverters:@Bean@ConditionalOnMissingBeanpublicHttpMessageConvertersmessageConverters(ObjectProvider>converters){returnnewHttpMessageConverters((Collection)Converters.lleect(Collection)converters.order))));}我们可以直接使用。那么如何使用呢?首先我们要搞清楚HttpInputMessage和HttpOutputMessage是干什么用的。HttpInputMessageHttpInputMessage表示一个HTTP输入消息,由请求头和可读的请求体组成,通常由服务器端的HTTP请求处理程序或客户端的HTTP响应处理程序实现。HttpInputMessage和HttpServletRequest是ServletRequest的扩展接口,提供HTTPServlet请求信息,还包括请求头和请求体,所以两者是相关的。只要弄清两者的实际关系,就可以让HttpMessageConverter读取并处理HttpServletRequest携带的请求信息。ServletServerHttpRequest老老实实发现:ServletServerHttpRequestServletServerHttpRequest不仅仅是HttpInputMessage的实现,它还持有一个HttpServletRequest实例属性,ServletServerHttpRequest的所有操作都是基于HttpServletRequest。我们可以通过构造向其中注入HttpServletRequest实例,让HttpMessageConverter间接处理HttpServletRequest。提取请求体的实战重点是在Servlet过滤器中使用HttpMessageConverter。不建议在SpringMVC中操作HttpServletRequest。我选择了FormHttpMessageConverter,它通常用于处理application/x-www-form-urlencoded请求。我们写一个过滤器来拦截提取正文的请求:();privatestaticFillendUrlencodedFiltertoryLoggerlog=LoggerF.class);@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException{StringcontentType=request.getContentType();MediaTypetype=StringUtils.hasText(contentType)?MediaType.valueOf(contentType):null;ServletServer=ServtRequestHttpRequestRequestRequestRequestRequestRequest空((HttpServletRequest)请求);if(formHttpMessageConverter.canRead(MultiValueMap.class,type)){MultiValueMapread=formHttpMessageConverter.read(null,serverHttpRequest);log.info("打印读取请求正文:{}",read);}}}然后使用Content-Typeapplication/x-www-form-urlencoded:POST/indHTTP/1.1Host:localhost:8080Content-Type:appli执行POST类型请求cation/x-www-form-urlencodedContent-Length:20a=b123&c=d123&e=f123consoleprint:printthereadrequestbody:{a=[b123],c=[d123],e=[f123]}ServletServerHttpResponse有ServletServerHttpRequest就有ServletServerHttpResponse,大致原理差不多它正好和ServletServerHttpRequest相反,如果我们需要去处理响应问题,比如想通过HttpServletResponse写个JSON响应,大概可以这么写:ServletServerHttpResponseservletServerHttpResponse=newServletServerHttpResponse(response);//使用jsonconverterMappingJackson2HttpMessageConvertermappingJackson2HttpMessageConverter=newMappingJackson2HttpMessageConverter();//authenticationreferstotheobjectinstancethatneedstobewrittenmappingJackson2HttpMessageConverter.write(authentication,MediaType.APPLICATION_JSON,servletServerHttpResponse);SummaryHttpMessageConverterabstractsthestrategyofHTTPmessageconversion,whichcanhelpushandlesomerequestresponseproblemsgracefully.Butonethingtonoteisthattherequestbodycanonlybereadonce,evenifitiswrappedinServletServerHttpRequest,payattentiontothedifferencefromHttpServletRequestWrapper.