当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

request.getInputStream()只能获取一次的问题

发表于: 2014-08-29   作者:ayaoxinchao   来源:转载   浏览:
摘要: 问题:在使用HTTP协议实现应用间接口通信时,服务端读取客户端请求过来的数据,会用到request.getInputStream(),第一次读取的时候可以读取到数据,但是接下来的读取操作都读取不到数据   原因: 1. 一个InputStream对象在被读取完成后,将无法被再次读取,始终返回-1; 2. InputStream并没有实现reset方法(可以重
问题:在使用HTTP协议实现应用间接口通信时,服务端读取客户端请求过来的数据,会用到request.getInputStream(),第一次读取的时候可以读取到数据,但是接下来的读取操作都读取不到数据
 
原因
1. 一个InputStream对象在被读取完成后,将无法被再次读取,始终返回-1;
2. InputStream并没有实现reset方法(可以重置首次读取的位置),无法实现重置操作;
 
解决方法(缓存读取到的数据)
1.使用requestsession等来缓存读取到的数据,这种方式很容易实现,只要setAttribute和getAttribute就行;
2.使用HttpServletRequestWrapper来包装HttpServletRequest,在MAPIHttpServletRequestWrapper中初始化读取request的InputStream数据,以byte[]形式缓存在其中,然后在Filter中将request转换为包装过的request;代码如下:
 
public class MAPIHttpServletRequestWrapper extends HttpServletRequestWrapper {
	
	private final byte[] body; // 报文

	public MAPIHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
		super(request);
		body = StreamUtil.readBytes(request.getInputStream());
	}
	
	@Override
	public BufferedReader getReader() throws IOException {
		return new BufferedReader(new InputStreamReader(getInputStream()));
	}
	
	@Override
	public ServletInputStream getInputStream() throws IOException {
		final ByteArrayInputStream bais = new ByteArrayInputStream(body);
		return new ServletInputStream() {
			
			@Override
			public int read() throws IOException {
				return bais.read();
			}
		};
	}

}
/**
 * @author Perlin.Yao
 * @date 2014年8月22日
 * @version 1.0
 */
public class HttpServletRequestReplacedFilter implements Filter {

	@Override
	public void destroy() {
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		ServletRequest requestWrapper = null;  
        if(request instanceof HttpServletRequest) {  
            requestWrapper = new MAPIHttpServletRequestWrapper((HttpServletRequest) request);  
        }  
        if(requestWrapper == null) {  
            chain.doFilter(request, response);  
        } else {  
            chain.doFilter(requestWrapper, response);  
        }  
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		
	}

}
  
<filter>
	<filter-name>requestFilter</filter-name>
	<filter-class>com.ulinkpay.mapi.common.web.HttpServletRequestReplacedFilter</filter-class>
</filter>
	
<filter-mapping>
	<filter-name>requestFilter</filter-name>
	<url-pattern>*.action</url-pattern>
</filter-mapping>
 
 

request.getInputStream()只能获取一次的问题

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
为什么要限制一分钟之内只能发送一次手机短信呢? 防止恶意攻击. 什么场景需要发送手机短信? (a)手机
The naughty signal function signal 函数的prototype: #include <signal.h> typedef void (
基于对话框的程序(mfc默认生成),重载OnEraseBkgnd函数,其它不动,若在OnPaint函数中不调用其基
系统对外提供的Solr查询接口,在来自外部调用的压力加大之后,就会出现solr查询报Read Timed Out的
今天一个同事问我nginx无访问正常访问且权限全都给的: 看下这里 这里是nginx访问控制日志: 这里是
一次奇怪的问题定位过程 简介 遇到的很奇怪的一个问题、在做数据统计时、先将测试数据存放到表中、
系统对外提供的 Solr 查询接口,在来自外部调用的压力加大之后,就会出现 solr 查询报 Read Timed O
private void button1_Click(object sender, EventArgs e) //登陆页面的第一栏的文本 要将它传到Mai
背景:客户反馈系统出现一个Bug,花了1天时间搞定,但是准备下发程序的时候发现我编译后的dll比目前
myeclipse 上安装 Maven3 环境准备: JDK 1.6 Maven 3.0.4 myeclipse 8.6.1 安装 Maven 之前要求先
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号