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. centos6安装oracle11g过程中报错Error in invoking target “install” of makefile ‘/home/oracle/app/oracle/product/11.2.0/dbhome_1/ctx/lib/ins_ctx.mk’

    报这个错误的原因是由于缺少compat_libstdc包所导致.安装即可 1.在http://www.rpm-find.net/linux/rpm2html/search.php?query=comp ...

  2. VUE项目 npm run build卡住不动,也不报错

    npm config set registry http://registry.cnpmjs.org try again npm run build 居然能动了....

  3. java面试一、1.5JVM

    免责声明:     本文内容多来自网络文章,转载为个人收藏,分享知识,如有侵权,请联系博主进行删除. 1.5.JVM JVM运行时内存区域划分

  4. VS中Debug与Release、_WIN32与_WIN64的区别

    一.Debug与Release 1.  区别 Debug——调试版,生成的.exe中包含很多调试信息,若直接发包,比较大: Release——发布版 2.  如何区分是Debug编译还是Release ...

  5. 10-Mock模拟接口返回数据

    1.安装mock 方法一:pip安装 命令行直接输入:pip install mock 方法二:官网下载mock安装包安装 下载安装包后,解压,命令行进入解压目录,执行python setup.py ...

  6. [编译] 2、minGW gcc在windows搭建编译win32程序环境

    1.普通下载一个MinGW程序.安装之后可以直接将MinGW目录拷贝到总工程的tool里面: demo_mesh_common tree -L 2 . ├── app ├── bin ├── buil ...

  7. iOS开发之ReactiveCocoa下的MVVM

    最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...

  8. Java并发编程基础——同步

    一.synchronized 关键字 1)synchronized 锁什么?锁对象.可能锁对象包括: this, 临界资源对象,Class 类对象.如同下面例子所示: package cn.test. ...

  9. WEB站点服务器安全配置

    WEB站点服务器安全配置   本文转自:i春秋社区   // 概述 // 熟悉网站程序 // 更改默认设置的必要性 // 目录分析与权限设置技巧 // 防止攻击其他要素 // 公司官网不可忽视的安全性 ...

  10. Visual Studio 开发(二):VS 2017配置FFmpeg开发环境

    在上篇文章Visual Studio 开发(一):安装配置Visual Studio Code 中,我们讲了一下如何配置VS CODE,来编写和调试C的代码.如果你已经使用VS Code回顾和复习好C ...