ServletRequest中getReader()和getInputStream()只能调用一次的解决办法-续网友

本文的实现根据网友的文章-ServletRequest中getReader()和getInputStream()只能调用一次的解决办法

我做的是springmvc项目,项目经理提出需求:每一个请求都要记录放到日志的功能,记录的内容有IP地址、请求的路径、和访问的参数,并定期转移日志。

遇到的问题就是:ServletRequest的getReader()和getInputStream()两个方法只能被调用一次,而且不能两个都调用。

文章请参考网友的文章,很细腻。但是看了之后可能需要思考一些事情才能解决这个问题。


好啦,开始show 代码啦。

1、Filter部分代码

package com.xxx.xxx.WebService.Filter;

import java.io.BufferedReader;
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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.json.JSONObject;

public class HttpServletRequestReplacedFilter implements Filter{
	private static final Log logger = LogFactory.getLog("requestLogInterceptor");
	@Override
	public void destroy() {
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		 ServletRequest requestWrapper = null;
         if(request instanceof HttpServletRequest) {
             requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);  
         }  
         if(null == requestWrapper) {
            chain.doFilter(request, response);
         } else {
        	 BufferedReader br = requestWrapper.getReader();
        	 String str = null,retStr="";
         	 while ((str = br.readLine()) != null) {
         		retStr += str;
     		 }
         	 
        	 String ip = requestWrapper.getRemoteAddr();
     		 StringBuffer url = ((HttpServletRequest) request).getRequestURL();
     		 JSONObject jo = new JSONObject();
     		 jo.put("ip", ip);
     		 jo.put("url", url.toString());
     		 jo.put("content", retStr);
     		 logger.info(jo);
             chain.doFilter(requestWrapper, response);
         }
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		
	}

}

2、BodyReaderHttpServletRequestWrapper部分代码

package com.xxx.xxx.WebService.Filter;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.lang.StringUtils;

public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
	private final byte[] body;  
    
    public BodyReaderHttpServletRequestWrapper(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();  
            }  
        };  
    } 
    
    /**
     * 通过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;
    }
    
}

3、web.xml中的代码


	springFilter
	com.xxx.xxx.WebService.Filter.HttpServletRequestReplacedFilter


	springFilter
	/*
配置好了,就可以测试一下啦

日志文件中产生了数据







你可能感兴趣的:(Springmvc,getReader,getInputStream,ServletRequest)