您的位置:首页 > 产品设计 > UI/UE

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

2016-12-06 18:15 549 查看
本文的实现根据网友的文章-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中的代码

<filter>
<filter-name>springFilter</filter-name>
<filter-class>com.xxx.xxx.WebService.Filter.HttpServletRequestReplacedFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置好了,就可以测试一下啦

日志文件中产生了数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐