request.get Parameeter()、request.get Input Stream()とrequest.get Reader()は一回しか使用できない問題を解決します.

5466 ワード

問題:Spring MVCブロックを使ってPOST要求中のJSON情報を取得する場合、request.get Reader()を使ってJSON情報を取得した後、POST要求は下に進まない.
 
理由:
1.Readerオブジェクトは読み取りが完了した後、再び読み取りできなくなり、常に-1に戻ります.
2.POSTも一つの流れですので、Reader方法を使ってからPOSTがtrueに戻りたいと言っても下に進まないです.
 
ソリューション:HttpServletRequest Wrapperを使用して、HttpServletRequestを包装し、BodyReader HttpServletRequest Wrapperで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からスプリングmvcのブロックを歩いて、何度も読み取ることができます.