spring MVC 获取request中的body体
来源:互联网 发布:淘宝异地客服兼职 编辑:程序博客网 时间:2024/06/05 11:27
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"></span>在项目中,客户端向服务端传送一组json数据,这组数据随着时间的推移可能会越来越大,可能会受到服务器对参数大小的限制的影响,因此,想直接将数据塞进request的body体中,继而发送给服务端,服务端直接将request中body 以流的方式读出来,并持久化。</span>
HttpServletRequest类中有两个方法 getInputStream() 和request.getReader() ,本以为可以直接快速搞定,但是运行程序时报异常:getInputStream() has already been called for this request ,经过查证,原来项目采用springmvc框架,框架内部已经读过request中流,所以当再次读取时,就读不到了,所以直接获取走不通了。
在网上问了问度娘,springmvc 中有一个注解@RequestBody 可以获取request中数据,部分代码如下:
@RequestMapping("/save")
public ModelAndView save(HttpServletRequest request,@RequestBody String s){
//具体操作 省略
}
运行过程中,还是有问题,但至少有进了一步,上述的String对象依然无法获取数据,这就有些纠结了,又开始问度娘和下载找spring的源码,了解@RequestBody的实现细节,发现获取body spring用了一系列的HttpMessageConverter 来实现,如:ByteArrayHttpMessageConverter,stringHttpMessageConverter ,spring自个实现的转换器,com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter【国产的json转换器,该转换器需要在配置文件中配置】,默认的转换器的初始化工作在RequestMappingHandlerAdapter这个类中实现
private List<HttpMessageConverter<?>> messageConverters;//转换器的集合
public RequestMappingHandlerAdapter() {StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();stringHttpMessageConverter.setWriteAcceptCharset(false); // See SPR-7316this.messageConverters = new ArrayList<HttpMessageConverter<?>>();this.messageConverters.add(new ByteArrayHttpMessageConverter());this.messageConverters.add(stringHttpMessageConverter);this.messageConverters.add(new SourceHttpMessageConverter<Source>());this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());}//初始化工作
找到这发现byte ,String的转换器已经初始化了,但是为啥还是拿不到String类型的数据呢,接着找关于converters相关的代码,有个setMessageConverters方法
/** * Provide the converters to use in argument resolvers and return value * handlers that support reading and/or writing to the body of the * request and response. */public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {this.messageConverters = messageConverters;}spring在解析xml过程中会调用该方法 ,从而将用到的converters注入进去,因此明白项目在启动的过程中重新设置了HttpMessageConverter ,而我需要的converter并没有注入进去,因此在xml中配置如下
<mvc:annotation-driven ><mvc:message-converters> <ref bean="fastJsonHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven><bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8" index="0"></constructor-arg> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> </list> </property> </bean> <bean id="byteHttpMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"> </bean> <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> <value>text/html;charset=UTF-8</value> </list> </property> <property name="features"> <list> <!-- <value>WriteMapNullValue</value> --> <value>QuoteFieldNames</value> <value>WriteDateUseDateFormat</value> </list> </property> </bean>
这时启动项目,可以拿到数据了。。。
因此,在遇到问题的时候,先按照自己的思路尝试着去解决,可能有时候有些问题确实不知道如何解决的时候,可以先查查网上有没有相关问题的解决方案,选择合适的方案,自然问题就迎刃而解了,但是个别的时候,会遇到相当棘手的问题,通过一系列方案都无法完美解决的时候,可以尝试去查阅源码,同过阅读源码,一会理解框架的开发者的设计思路,只要顺着他们的思路,我们的问题自然就不是问题了。
最后,多读读优秀的开源项目的源码。
附:遍历转换器的代码
AbstractMessageConverterMethodArgumentResolver
/** * Creates the method argument value of the expected parameter type by reading * from the given HttpInputMessage. * * @param <T> the expected type of the argument value to be created * @param inputMessage the HTTP input message representing the current request * @param methodParam the method argument * @param targetType the type of object to create, not necessarily the same as * the method parameter type (e.g. for {@code HttpEntity<String>} method * parameter the target type is String) * @return the created method argument value * @throws IOException if the reading from the request fails * @throws HttpMediaTypeNotSupportedException if no suitable message converter is found */@SuppressWarnings("unchecked")protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage,MethodParameter methodParam, Type targetType) throws IOException, HttpMediaTypeNotSupportedException {MediaType contentType = inputMessage.getHeaders().getContentType();if (contentType == null) {contentType = MediaType.APPLICATION_OCTET_STREAM;}Class<?> contextClass = methodParam.getDeclaringClass();Map<TypeVariable, Type> map = GenericTypeResolver.getTypeVariableMap(contextClass);Class<T> targetClass = (Class<T>) GenericTypeResolver.resolveType(targetType, map);for (HttpMessageConverter<?> converter : this.messageConverters) {if (converter instanceof GenericHttpMessageConverter) {GenericHttpMessageConverter genericConverter = (GenericHttpMessageConverter) converter;if (genericConverter.canRead(targetType, contextClass, contentType)) {if (logger.isDebugEnabled()) {logger.debug("Reading [" + targetType + "] as \"" +contentType + "\" using [" + converter + "]");}return genericConverter.read(targetType, contextClass, inputMessage);}}if (targetClass != null) {if (converter.canRead(targetClass, contentType)) {if (logger.isDebugEnabled()) {logger.debug("Reading [" + targetClass.getName() + "] as \"" +contentType + "\" using [" + converter + "]");}return ((HttpMessageConverter<T>) converter).read(targetClass, inputMessage);}}}throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);}
- spring MVC 获取request中的body体
- Spring MVC获取request
- spring MVC 中获取request
- spring mvc获取request HttpServletRequest
- spring mvc Service 获取request
- SPRING MVC获取request参数方法:
- Spring MVC中获取request对象
- spring mvc 获取到request response @ModelAttribute
- spring mvc 在control外获取request
- Spring MVC中获取request ,response
- spring 将request body 转存...
- 显示HttpServletRequest request中的body
- beego 获取 Request Body 里的内容
- spring mvc中获取request、response对象方法
- Spring MVC怎么获取request的请求参数
- Spring MVC 注解@ResponseBody或流获取http请求body的json字符串
- 通过 Spring RestTemplate 调用带请求体的 Delete 方法(Delete With Request Body)
- spring获取request,session
- 设计模式-工厂
- 第十六周程序阅读(2)
- [Java]Session,Cookie知识与应用
- CSS布局属性
- HDU1561 The more, The Better(树形DP)
- spring MVC 获取request中的body体
- C++学习笔记 代替define
- JAVA——File类
- 汉诺塔的确切解
- 定制tomcat访问日志
- Visual Studio2008 和2010 运行程序出现的黑框立即消失解决方法
- LeetCode:Sum Root to Leaf Numbers
- Yandex.Algorithm 2016 Online Round 2 题解(待补)
- leetcode 118 Pascal's Triangle