request.getInputStream()只能获取一次的问题
2016-08-04 17:06
946 查看
问题
在使用HTTP协议实现应用间接口通信时,服务端读取客户端请求过来的数据,会用到request.getInputStream(),第一次读取的时候可以读取到数据,但是接下来的读取操作都读取不到数据原因
一个InputStream对象在被读取完成后,将无法被再次读取,始终返回-1;InputStream并没有实现reset方法(可以重置首次读取的位置),无法实现重置操作;
解决方法(缓存读取到的数据)
使用request、session等来缓存读取到的数据,这种方式很容易实现,只要setAttribute和getAttribute就行;使用HttpServletRequestWrapper来包装HttpServletRequest,在MAPIHttpServletRequestWrapper中初始化读取request的InputStream数据,以byte[]形式缓存在其中,然后在Filter中将request转换为包装过的request;代码如下:
package com.paddypower.financials.market.management.rest.logging; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.commons.io.IOUtils; public class LoggerFilter implements Filter { private Auditor auditor; public void destroy() { // Nothing to do } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ResettableStreamHttpServletRequest wrappedRequest = new ResettableStreamHttpServletRequest( (HttpServletRequest) request); // wrappedRequest.getInputStream().read(); String body = IOUtils.toString(wrappedRequest.getReader()); auditor.audit(wrappedRequest.getRequestURI(),wrappedRequest.getUserPrincipal(), body); wrappedRequest.resetInputStream(); chain.doFilter(wrappedRequest, response); } public void init(FilterConfig arg0) throws ServletException { // Nothing to do } private static class ResettableStreamHttpServletRequest extends HttpServletRequestWrapper { private byte[] rawData; private HttpServletRequest request; private ResettableServletInputStream servletStream; public ResettableStreamHttpServletRequest(HttpServletRequest request) { super(request); this.request = request; this.servletStream = new ResettableServletInputStream(); } public void resetInputStream() { servletStream.stream = new ByteArrayInputStream(rawData); } @Override public ServletInputStream getInputStream() throws IOException { if (rawData == null) { rawData = IOUtils.toByteArray(this.request.getReader()); servletStream.stream = new ByteArrayInputStream(rawData); } return servletStream; } @Override public BufferedReader getReader() throws IOException { if (rawData == null) { rawData = IOUtils.toByteArray(this.request.getReader()); servletStream.stream = new ByteArrayInputStream(rawData); } return new BufferedReader(new InputStreamReader(servletStream)); } private class ResettableServletInputStream extends ServletInputStream { private InputStream stream; @Override public int read() throws IOException { return stream.read(); } } } public void setAuditor(Auditor auditor) { this.auditor = auditor; } }
相关文章推荐
- request.getInputStream()只能获取一次的问题
- request.getInputStream()只能获取一次的问题
- 浅谈request.getinputstream只能读取一次的问题
- 解决request.getInputStream()只能读取一次的问题
- 浅谈request.getinputstream只能读取一次的问题
- Servlet的Request.getInputStream()只能读取一次问题
- Servlet的Request.getInputStream()只能读取一次问题
- Servlet的Request.getInputStream()只能读取一次问题
- Servlet的Request.getInputStream()只能读取一次问题
- 解决request.getParameter() 、 request.getInputStream()和request.getReader()只能使用一次的问题
- request.getinputstream只能读取一次
- 拦截器中,request中getReader()和getInputStream()只能调用一次,构建可重复读取inputStream的request.
- 浅谈图片上传利用request.getInputStream()获取文件流时遇到的问题
- Servlet的Request.getInputStream()只能读取一次
- request的getReader()和getInputStream()只能读取一次
- 关于ServletRequest servletRequest中获取的流getInputStream()和.getReader()的方法只能调用一次的解决方法
- 关于ServletRequest servletRequest中获取流的方法getInputStream()和.getReader()只能获取一次的方法
- HttpServletRequest.getInputStream() 只能读取一次
- spring boot 学习笔记(5) 解决HttpServletRequest inputStream只能读取一次的问题
- request.getparameter() 获取中文出现乱码 问题