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>
相關文章
相關標籤/搜索