springMVC列印請求資訊日誌,如請求頭,請求體,請求路徑等
阿新 • • 發佈:2018-12-12
處理類LoggingFilter :
package com.zqsign.app.privatearbitrate.interceptor; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; 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.log4j.Logger; import com.alibaba.fastjson.JSONObject; public class LoggingFilter implements Filter { Logger logger = Logger.getLogger(LoggingFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub javax.servlet.http.HttpServletRequest req = (javax.servlet.http.HttpServletRequest)request; Map<String, Object> map = new HashMap<String, Object>(); HttpServletRequest requestWrapper = new RepeatedlyReadRequestWrapper(req); try { // Get request URL. map.put("URL", req.getRequestURL()); map.put("Method", req.getMethod()); map.put("Protocol",req.getProtocol()); // 獲取header資訊 List<Map<String,String>> headerList = new ArrayList<>(); Map<String,String> headerMaps = new HashMap<String,String>(); for(Enumeration<String> enu = req.getHeaderNames();enu.hasMoreElements();){ String name = enu.nextElement(); headerMaps.put(name,req.getHeader(name)); } headerList.add(headerMaps); map.put("headers", headerList); //獲取parameters資訊 List<Map<String,String>> parameterList = new ArrayList<>(); Map<String,String> parameterMaps = new HashMap<String,String>(); for(Enumeration<String> names = req.getParameterNames();names.hasMoreElements();){ String name = names.nextElement(); parameterMaps.put(name, req.getParameter(name)); } parameterList.add(parameterMaps); map.put("parameters", parameterList); String line = ""; // 獲取請求體資訊 if (req.getMethod().equalsIgnoreCase("POST")) { int len = req.getContentLength(); char[] buf = new char[len]; int bufcount = requestWrapper.getReader().read(buf); if (len > 0 && bufcount <= len) { line = String.copyValueOf(buf).substring(0, bufcount); } } else if (req.getMethod().equalsIgnoreCase("GET")) { int idx = req.getRequestURL().indexOf("?"); if (idx != -1) { line = req.getRequestURL().substring(idx + 1); } else { line = null; } } if (line != null) { map.put("Context", new String[] { line }); } logger.info("接收請求報文:\n"+JSONObject.toJSONString(map)); chain.doFilter(requestWrapper, response); } catch (IOException ex) { ex.printStackTrace(); } } @Override public void destroy() { // TODO Auto-generated method stub } }
RepeatedlyReadRequestWrapper類:
package com.zqsign.app.privatearbitrate.interceptor; import org.apache.commons.lang3.StringUtils; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset; /** * @author lidanyang * @date 2018/7/4 */ public class RepeatedlyReadRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; public RepeatedlyReadRequestWrapper(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() { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener listener) { } @Override public int read() { 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; } }
web.xml配置:
<filter> <filter-name>requestCopyFilter</filter-name> <filter-class>com.zqsign.app.privatearbitrate.interceptor.RepeatedlyReadFilter</filter-class> <async-supported>true</async-supported> </filter> <filter-mapping> <filter-name>requestCopyFilter</filter-name> <url-pattern>/local/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
總結:輸出的請求日誌如下:
{
"Context": ["{\t\"caseCategoryInfoViewModel\": {\t\t\"agentInfoEntity\": {\t\t\t\"address\": \"sdfas\",\t\t\t\"agentType\": \"律師代理\",\t\t\t\"caseCategoryCode\": \"1513\",\t\t\t\"company\": \"fasdfa\",\t\t\t\"email\": \"[email protected]\",\t\t\t\"identityNo\": \"362226198908241213\",\t\t\t\"identityType\": \"身份證\",\t\t\t\"litigantType\": \"申請人\",\t\t\t\"mobile\": \"18615412359\",\t\t\t\"name\": \"fsdfas\",\t\t\t\"power\": \"一般代理\",\t\t\t\"powerDetail\": \"\",\t\t\t\"principal\": \"fasdf\",\t\t\t\"sex\": \"男\",\t\t\t\"uuid\": \"402882d8662900c601662907e2dc0002\"\t\t},\t\t\"applicantInfoEntity\": {\t\t\t\"addresses\": \"dfasdfasd\",\t\t\t\"caseCategoryCode\": \"1513\",\t\t\t\"contact\": \"sdfasf\",\t\t\t\"email\": \"[email protected]\",\t\t\t\"identityNo\": \"123456789123456QWE\",\t\t\t\"identityType\": \"組織機構程式碼證\",\t\t\t\"legalRepresent\": \"fasdf\",\t\t\t\"mobile\": \"18615412359\",\t\t\t\"name\": \"fasdfa\",\t\t\t\"nature\": \"企業\",\t\t\t\"post\": \"行長\",\t\t\t\"uuid\": \"402882d8662900c601662907e2d80001\"\t\t},\t\t\"caseCategoryEvidenceEntityList\": [],\t\t\"caseCategoryInfoEntity\": {\t\t\t\"appealTemplate\": \"fsafsd\",\t\t\t\"appealType\": 1,\t\t\t\"businessCode\": \"sdfas\",\t\t\t\"businessName\": \"fasdfas\",\t\t\t\"caseCategoryCode\": \"1513\",\t\t\t\"caseCategoryName\": \"fsdfasdfad\",\t\t\t\"caseCategoryStatus\": -1,\t\t\t\"commissionCode\": \"gzac\",\t\t\t\"createTime\": 1538286674000,\t\t\t\"platformName\": \"sfa\",\t\t\t\"tenantName\": \"fasdfa\",\t\t\t\"uuid\": \"402882d8662900c601662907e2b50000\",\t\t\t\"zqid\": \"ZQf31ad1a694ab4105800d2aa90389f67f\"\t\t}\t}}"],
"headers": [{
"content-length": "1437",
"cookie": "SESSION=e32500b2-c1e9-499e-a452-09a202ddd5ff",
"postman-token": "6556ef77-7c56-4fc3-aaa1-917d3e4f0b17",
"host": "localhost:8083",
"content-type": "application/json",
"connection": "keep-alive",
"cache-control": "no-cache",
"accept-encoding": "gzip, deflate",
"user-agent": "PostmanRuntime/7.1.1",
"accept": "*/*"
}],
"Method": "POST",
"Protocol": "HTTP/1.1",
"parameters": [{}],
"URL": "http://localhost:8083/web/local/case-category-info/deployment"
} >
作用:用來排查前後端互動時因請求資訊不一致所引起的問題。