---恢复内容开始---
今天领导安排给我一个活,在web.xml添加一个拦截器,日志打印出请求和响应的参数,搞了一下午,现在再次做一个笔记。
先不急着上代码,我们先要理清整个http请求的逻辑,
一次完整的HTTP请求过程从TCP三次握手建立连接成功后开始,客户端按照指定的格式开始向服务端发送HTTP请求,服务端接收请求后,解析HTTP请求,处理完业务逻辑,最后返回一个HTTP的响应给客户端,HTTP的响应内容同样有标准的格式。无论是什么客户端或者是什么服务端,大家只要按照HTTP的协议标准来实现的话,那么它一定是通用的。HTTP请求格式主要有四部分组成,分别是:请求行、请求头、空行、消息体,每部分内容占一行
在看spring mvc的接收到参数并响应的过程:发送请求,委托请求给处理器,处理器在调用业务员对象,返回视图模型,返回视图给控制器,控制器在调用视图,返回给控制器,在返回给前台
现在我们上代码:首先我们定义个人filter类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UrlFilter implements Filter {
static Logger logger = LoggerFactory.getLogger(UrlFilter.class);
ServletContext context;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter) throws IOException, ServletException {
HttpServletRequest r = (HttpServletRequest) request;
String path = r.getQueryString();
if (path == null) {
Map<String, String> map = new HashMap<String, String>();
Enumeration headerNames = ((HttpServletRequest) request).getHeaderNames();
while (headerNames.hasMoreElements()) {//循环遍历Header中的参数,把遍历出来的参数放入Map中
String key = (String) headerNames.nextElement();
String value = ((HttpServletRequest) request).getHeader(key);
map.put(key, value);
}
System.out.println(map.toString());
path = map.toString();
}
String url = r.getRequestURI();
RequestWrapper requestWrapper = null;
String repalceUrl = url.replaceAll("/", "");
if (null != repalceUrl) {
repalceUrl = repalceUrl.trim();
} else {
return;
}
logger.info("\n\n----------------- url:" + url + " & queryString:" + path);
ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
if (request instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) request);
try {
Map map = request.getParameterMap();
logger.info("map:" + map);
BufferedReader bufferedReader = requestWrapper.getReader();
String line;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
logger.info("request.getReader:" + sb.toString());
} catch (Exception e) {
// TODO: handle exception
logger.error("p2ps doFilter :", e);
}
}
if (null == requestWrapper) {
filter.doFilter(request, response);
} else {
filter.doFilter(requestWrapper, responseWrapper);
}
String result = new String(responseWrapper.getResponseData());
response.setContentLength(-1);//解决可能在运行的过程中页面只输出一部分
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write(result);
out.flush();
out.close();
logger.info("\n return data:" + result);
logger.info("\n---------------- end url:" + url + " httpstatus:" + ((HttpServletResponse) response).getStatus() + "");
}
public void init(FilterConfig filterConfig) throws ServletException {
context = filterConfig.getServletContext();
}
}
再定义一个接收请求的处理类
import com.demo.utils.StreamUtil; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * 复制request中的bufferedReader中的值 * * @date 2016年9月1日 上午10:53:06 */ public class RequestWrapper extends HttpServletRequestWrapper { private final byte[] body; /** * 这个必须加,复制request中的bufferedReader中的值 * * @param request * @throws IOException */ public RequestWrapper(HttpServletRequest request) throws IOException { super(request); //body = StreamUtil.readBytes(request.getReader(), "UTF-8"); body = StreamUtil.getByteByStream(request.getInputStream()); } @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() { public boolean isFinished() { return false; } public boolean isReady() { return false; } public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return bais.read(); } }; } }
import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class ResponseWrapper extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer = null;//输出到byte array private ServletOutputStream out = null; private PrintWriter writer = null; public ResponseWrapper(HttpServletResponse resp) throws IOException { super(resp); buffer = new ByteArrayOutputStream();// 真正存储数据的流 out = new WapperedOutputStream(buffer); writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding())); } /** 重载父类获取outputstream的方法 */ @Override public ServletOutputStream getOutputStream() throws IOException { return out; } /** 重载父类获取writer的方法 */ @Override public PrintWriter getWriter() throws UnsupportedEncodingException { return writer; } /** 重载父类获取flushBuffer的方法 */ @Override public void flushBuffer() throws IOException { if (out != null) { out.flush(); } if (writer != null) { writer.flush(); } } @Override public void reset() { buffer.reset(); } /** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */ public byte[] getResponseData() throws IOException { flushBuffer(); return buffer.toByteArray(); } /** 内部类,对ServletOutputStream进行包装 */ private class WapperedOutputStream extends ServletOutputStream { private ByteArrayOutputStream bos = null; public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException { bos = stream; } @Override public void write(int b) throws IOException { bos.write(b); } @Override public void write(byte[] b) throws IOException { bos.write(b, 0, b.length); } public boolean isReady() { return false; } public void setWriteListener(WriteListener writeListener) { } } }
在web.xml 中添加刚编写的自定义filter类
<filter> <filter-name>UrlFilter</filter-name> <filter-class>com.demo.demo2.UrlFilter</filter-class><!--注意,此路径换成您自己项目的路径--> </filter> <filter-mapping> <filter-name>UrlFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
在编写一个contrller 测试调用就ok了。
写的不好请海涵,有错的地方请留言,我及时更正
下面是我参考的文章路径:http://www.voidcn.com/blog/wuhenzhangxing/article/p-6299832.html
http://blog.jobbole.com/106632/
---恢复内容结束---
原文:http://www.cnblogs.com/xincunyiren/p/7248034.html