HTTP请求中的是字符串数据:

 //字符串读取

 void charReader(HttpServletRequest request) {
BufferedReader br = request.getReader();
String str, wholeStr = "";
while((str = br.readLine()) != null){
wholeStr += str;
}
System.out.println(wholeStr);
}
//二进制读取 void binaryReader(HttpServletRequest request) {
int len = request.getContentLength();
ServletInputStream iii = request.getInputStream();
16 byte[] buffer = new byte[len];
iii.read(buffer, 0, len);
}

注意:

request.getInputStream();   request.getReader();  和request.getParameter("key");

这三个函数中任何一个函数执行一次后(可正常读取body数据),之后再执行就无效了。

解决方法: 包装HttpServletRequest对象,缓存body数据,再次读取的时候将缓存的值写出

 package com.nd.sdp.formatastic.common.interceptor;

 import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*; /**
* @author weihainan.
* @since 0.1 created on 2017/2/23.
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { private final String body; public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
} @Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
} @Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
} public String getBody() {
return this.body;
}
}

使用Filter替换HttpServletRequest对象

 package com.nd.sdp.formatastic.common.interceptor;

 import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException; /**
* @author weihainan.
* @since 0.1 created on 2017/2/23.
*/
@WebFilter(filterName = "httpServletRequestWrapperFilter", urlPatterns = "/*")
public class HttpServletRequestWrapperFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException { ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest) {
requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
}
if (null == requestWrapper) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
} } @Override
public void destroy() { }
}

HttpServetRequest读取body只能一次的问题的更多相关文章

  1. Servlet的Request.getInputStream()只能读取一次问题

    Servlet的Request.getInputStream()只能读取一次问题 这个星期公司的项目接口进行改造,公司的接口有的采用了WebService的方式,有的使用的是Http协议+Servle ...

  2. Andriod读取XML问题

    终于搞明白了,Andriod读取资源只能在asserts文件夹下或者scard上,其他地方是不行的. 文件加在XML后,就可以读了. 一句话就搞定了: InputStream istr = getAs ...

  3. java读取各类型的文件

    java读取各类型的文件 用到的几个包 bcmail-jdk14-132.jar/bcprov-jdk14-132.jar/checkstyle-all-4.2.jar/FontBox-0.1.0-d ...

  4. 读取Webpage表中的内容

    nutch将从网页中抓取到的信息放入hbase数据库中,默认情况下表名为$crawlId_webpage,但表中的内容以16进制进行表示,直接scan或者通过Java API进行读取均只能读取到16进 ...

  5. java读取各种类型文件

    用到的几个包 bcmail-jdk14-132.jar/bcprov-jdk14-132.jar/checkstyle-all-4.2.jar/FontBox-0.1.0-dev.jar/lucene ...

  6. python通过标准输入读取内容,读取键盘输入的内容?接收用户输入?

    需求说明: 在交互式脚本中,需要用户手动输入内容,并对内容进行处理.在这里记录下通过 python的内置函数input()读取标注输入的内容.默认的标准输入是键盘. 操作过程: 1.通过input() ...

  7. java读取配置文件常用的四种方式

    配置文件 放置在src下面 obj.properties className=com.store.order.dao.impl.OrderDaoImpl 方式一 @Test public void t ...

  8. 读取Webpage表中的内容 分类: H3_NUTCH 2015-02-10 14:59 418人阅读 评论(0) 收藏

    nutch将从网页中抓取到的信息放入hbase数据库中,默认情况下表名为$crawlId_webpage,但表中的内容以16进制进行表示,直接scan或者通过Java API进行读取均只能读取到16进 ...

  9. FileInputStream读取的两种方法:逐字节读;以字节数组读取

    1:read() : 从输入流中读取数据的下一个字节,返回0到255范围内的int字节值.如果因为已经到达流末尾而没有可用的字节,则返回-1.在输入数据可用.检测到流末尾或者抛出异常前,此方法一直阻塞 ...

随机推荐

  1. vue中v-model动态生成的实例详解

    每一行有一个input和一个select,其中行数是根据服务器返回的json数据动态变化的.那么问题来了,我们要怎样动态生成v-model? <template> <div> ...

  2. Effective Java -- 使可变性最小化

    为了使类成为不可变的,应该遵循以下五条原则: 1. 不要提供任何会下盖对象状态的方法 2. 保证类不会被扩展 3. 使所有的域都是final的 4. 使所有的域都成为私有的 5. 确保对于任何可变组件 ...

  3. Effective Java --使类和成员的可访问性最小化

    尽可能地降低可访问性 接口和成员变量访问级别四种访问级别: 私有的(private) --- 只有在生命该成员的顶层类内部才可以访问 包级私有的(package-private) --- 缺省的&qu ...

  4. VS2017离线安装入门与出家

    重做系统,并且VS2017也发布有一段时间了,可以试试了. 于是网上搜了下,离线安装要下载他的安装工具. https://www.visualstudio.com/zh-hans/downloads/ ...

  5. es6面向对象

    <script> class user{ constructor(name,age){ this.name=name; this.age=age; } showName(){ alert( ...

  6. Git使用(二、分支的创建和上传)

    介绍使用TortoiseGit创建分支并push到gitlab项目库,转载请注明出处. 一.创建一个新的文件夹,把要待编辑的工程从gitlab上pull到该文件夹. 其中URL从gitlab的对应项目 ...

  7. 数据库的Connection、Cursor两大对象

    Python 数据库图解流程 Connection.Cursor比喻 Connection()的参数列表 host,连接的数据库服务器主机名,默认为本地主机(localhost). user,连接数据 ...

  8. Exp3 免杀原理与实践_05齐帅

    Exp3 免杀原理与实践 20154305_齐帅 想要弄懂免杀,一定得先把基础问题弄明白啊~~ 一.基础问题回答 (1)杀软是如何检测出恶意代码的? - -检测特征码: 依靠分析总结出计算机病毒中常出 ...

  9. 【CF486E】LIS of Sequence题解

    [CF486E]LIS of Sequence题解 题目链接 题意: 给你一个长度为n的序列a1,a2,...,an,你需要把这n个元素分成三类:1,2,3: 1:所有的最长上升子序列都不包含这个元素 ...

  10. 不同后台服务器共用同一session

    建一个类继承SessionStateStoreProviderBase类,override Initialize.SetAndReleaseItemExclusive.ReleaseItemExclu ...