解决request.getParameter() 、 request.getInputStream()和request.getReader()只能使用一次的问题

问题:在使用SpringMVC拦截器获取POST请求中的JSON信息的时候,使用request.getReader()方法获取JSON信息后,POST请求就不往下走了,
 
原因
1. 一个Reader对象在被读取完成后,将无法被再次读取,始终返回-1;
2. POST也是一种流,所以使用Reader方法后,POST请求返回true也不往下走了
 
解决方案:使用HttpServletRequestWrapper来包装HttpServletRequest,在BodyReaderHttpServletRequestWrapper中初始化读取request的Reader数据,以byte[]形式缓存在其中,然后在Filter中将request转换为包装过的request;代码如下:
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;  
            System.out.println(httpServletRequest.getContentType());
            System.out.println(httpServletRequest.getContextPath());
            System.out.println(httpServletRequest.getRemoteHost());
            System.out.println(httpServletRequest.getMethod());
            if ("POST".equals(httpServletRequest.getMethod().toUpperCase())  
                    ) {  
            	//&& httpServletRequest.getContentType().equalsIgnoreCase(  
           // "application/json")
                requestWrapper = new BodyReaderHttpServletRequestWrapper(  
                        (HttpServletRequest) request);  
            }  
        }  
  
        if (requestWrapper == null) {  
            chain.doFilter(request, response);  
        } else {  
            chain.doFilter(requestWrapper, response);   
        }  
    }  
  
    @Override  
    public void init(FilterConfig arg0) throws ServletException {  
  
    }  
  
}  
public class BodyReaderHttpServletRequestWrapper extends  
        HttpServletRequestWrapper {  
      
    private final byte[] body;  
  
    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {  
        super(request);  
        Enumeration e = request.getHeaderNames()   ;    
         while(e.hasMoreElements()){    
             String name = (String) e.nextElement();    
             String value = request.getHeader(name);    
                 
         }    
        body = HttpHelper.getBodyString(request).getBytes(Charset.forName("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 String getHeader(String name) {  
        return super.getHeader(name);  
    }  
  
    @Override  
    public Enumeration getHeaderNames() {  
        return super.getHeaderNames();  
    }  
  
    @Override  
    public Enumeration getHeaders(String name) {  
        return super.getHeaders(name);  
    }  
      
}
public class HttpHelper {  
    /** 
     * 获取请求Body 
     * 
     * @param request 
     * @return 
     */  
    public static String getBodyString(ServletRequest request) {  
        StringBuilder sb = new StringBuilder();  
        InputStream inputStream = null;  
        BufferedReader reader = null;  
        try {  
            inputStream = request.getInputStream();  
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));  
            String line = "";  
            while ((line = reader.readLine()) != null) {  
                sb.append(line);  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            if (inputStream != null) {  
                try {  
                    inputStream.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
            if (reader != null) {  
                try {  
                    reader.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
        return sb.toString();  
    }  
}  
web.xml配置文件
	  
	    HttpServletRequestReplacedFilter  
	    com.xxx.xxx.xxx.xxx.util.HttpServletRequestReplacedFilter  




	  
	  
	    HttpServletRequestReplacedFilter  
	    /*  
	  





这样运行的时候就会先走Filter再走springmvc的拦截器了,就可以多次读取了
 

你可能感兴趣的:(springmvc)