zoukankan      html  css  js  c++  java
  • 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 

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

  • 相关阅读:
    cxVerticalGrid赋值是实时更新
    cxGrid类似pagecontrol的效果
    cxgrid属性说明,每次用的时候费时费力查找。
    做一个平均数,合计数的sql查询
    FDMemTable 提示操作速度尤其是循环
    手机号码验证
    取字符串长度
    DELPHI 获取本月 的第一天 和 最后一天
    SQL Server 断开某个数据库所有连接(还原的时候需要)转自用保留
    元宇宙六大核心技术
  • 原文地址:https://www.cnblogs.com/zrlbiog/p/7729336.html
Copyright © 2011-2022 走看看