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

问题

在使用HTTP协议实现应用间接口通讯时,服务端读取客户端请求过来的数据,会用到request.getInputStream(),第一次读取的时候能够读取到数据,可是接下来的读取操做都读取不到数据web

缘由

  1. 一个InputStream对象在被读取完成后,将没法被再次读取,始终返回-1;
  2. InputStream并无实现reset方法(能够重置首次读取的位置),没法实现重置操做;

解决方法(缓存读取到的数据):

1.使用request、session等来缓存读取到的数据,这种方式很容易实现,只要setAttribute和getAttribute就行; 2.使用HttpServletRequestWrapper来包装HttpServletRequest,在MAPIHttpServletRequestWrapper中初始化读取request的InputStream数据,以byte[]形式缓存在其中,而后在Filter中将request转换为包装过的request;代码以下:api

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();
			}
		};
	}

}

filter代码:缓存

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 {
		
	}

}

web.xml配置:session

<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>
相关文章
相关标签/搜索