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 

 

---恢复内容结束---

posted @ 2017-12-15 16:25  北境  阅读(10699)  评论(1编辑  收藏  举报