---恢復內容開始---
今天領導安排給我一個活,在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/
---恢復內容結束---