springMVC使用request.getInputStream()获取流为空
---恢复内容开始---
如题,因为springMVC已经读取过一次输入流,所以在Controller再次获取流为空
解决方法,先将RequestBody保存为一个byte数组,然后通过Servlet自带的HttpServletRequestWrapper类覆盖getReader()和getInputStream()方法,使流从保存的byte数组读取。然后再Filter中将ServletRequest替换为ServletRequestWrapper。代码如下:
1.下面为添加的过滤器,该过滤器放到web.xml最上面
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import com.sinosoft.sss.utils.MAPIHttpServletRequestWrapper; 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) { HttpServletRequest httpServletRequest = (HttpServletRequest) request; if("POST".equals(httpServletRequest.getMethod().toUpperCase())){ 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 { } }
2.web.xml文件
<filter> <filter-name>requestFilter</filter-name> <filter-class>com.sinosoft.sss.filter.HttpServletRequestReplacedFilter</filter-class> </filter> <filter-mapping> <filter-name>requestFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3.覆盖HttpServletRequestWrapper类getReader()和getInputStream()方法
import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.apache.commons.lang.StringUtils; public class MAPIHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; public MAPIHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); body = readBytes(request.getReader(), "utf-8"); } @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(); } @Override public boolean isFinished() { // TODO Auto-generated method stub return false; } @Override public boolean isReady() { // TODO Auto-generated method stub return false; } @Override public void setReadListener(ReadListener readListener) { // TODO Auto-generated method stub } }; } /** * 通过BufferedReader和字符编码集转换成byte数组 * @param br * @param encoding * @return * @throws IOException */ private byte[] readBytes(BufferedReader br,String encoding) throws IOException{ String str = null,retStr=""; while ((str = br.readLine()) != null) { retStr += str; } if (StringUtils.isNotBlank(retStr)) { return retStr.getBytes(Charset.forName(encoding)); } return null; } }
参考:http://www.cnblogs.com/ocean-sky/p/6899613.html
http://www.cnblogs.com/csliwei/p/5557353.html
---恢复内容结束---