有个需要日志记录http请求和响应的需求,通过一个logFilter来实现
一、入参打印
JSON.toJSONString(servletRequest.getParameterMap()));
二、出参打印
ServletResponse中将输出流,直接获取流并不能获取流中的数据,只可以改写响应流,替换响应内容;
所以需要重写ServletResponse来保存传到输出流的内容;
com.github.isrsal.logging.ResponseWrapper 则实现了这个需求,将输出流的内容保存在了字节数组缓冲区;
需要引入的依赖:
com.github.isrsal
spring-mvc-logger
0.2
log4j
log4j
javax.servlet
servlet-api
org.slf4j
slf4j-log4j12
获取出参的方法:
ResponseWrapper responseWrapper = new ResponseWrapper(Thread.currentThread().getId(), (HttpServletResponse) servletResponse);
filterChain.doFilter(servletRequest, responseWrapper);
String str = new String(responseWrapper.toByteArray(), responseWrapper.getCharacterEncoding());
三、完整的出入参打印
importcom.alibaba.fastjson.JSON;importcom.github.isrsal.logging.RequestWrapper;importcom.github.isrsal.logging.ResponseWrapper;importorg.apache.catalina.connector.RequestFacade;importorg.apache.catalina.connector.ResponseFacade;importorg.apache.commons.logging.Log;importorg.apache.commons.logging.LogFactory;importorg.apache.logging.log4j.ThreadContext;importorg.springframework.stereotype.Component;importorg.springframework.util.StringUtils;import javax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;importjava.io.UnsupportedEncodingException;importjava.net.URLDecoder;importjava.util.HashMap;importjava.util.Map;importjava.util.UUID;/*** @Author: chenhao
* @Date: 2018-06-14*/@Component
@WebFilter(filterName= "logFilter", urlPatterns = "/*")public class LogFilter implementsFilter {private static final Log log = LogFactory.getLog(LogFilter.class);private static final String ignoreUrlRegex = ".*((pay/)|(/index)|(/index/.*)|([.]((html)|(jsp)|(css)|(js)|(gif)|(png))))$";
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throwsIOException, ServletException {
ThreadContext.put("TId", UUID.randomUUID().toString());
ResponseWrapper responseWrapper= newResponseWrapper(Thread.currentThread().getId(), (HttpServletResponse) servletResponse);
HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
RequestWrapper requestWrapper= new RequestWrapper(Thread.currentThread().getId(), httpServletRequest);//请求html页面、js不打印日志
if(httpServletRequest.getRequestURI().matches(ignoreUrlRegex)) {
ThreadContext.clearAll();
filterChain.doFilter(servletRequest, responseWrapper);return;
}
Map params;//记录入参
log.info("请求的URL:" +httpServletRequest.getRequestURI());
filterChain.doFilter(requestWrapper, responseWrapper);//打印from格式的入参信息
params =servletRequest.getParameterMap();if (null != params && params.size() != 0) {
log.info("入参:" +JSON.toJSONString(params));
}else{//打印json格式的入参信息
String charEncoding = requestWrapper.getCharacterEncoding() != null ? requestWrapper.getCharacterEncoding() : "UTF-8";
log.info("入参" + newString(requestWrapper.toByteArray(), charEncoding));
}//记录出参
String outParam = newString();//记录出参响应头
params = newHashMap();//如果响应头存在errorCode则打印,除文件下载外均不存在
try{
params.put("errorCode", ((ResponseFacade) servletResponse).getHeader("errorCode"));
params.put("errorMsg", (URLDecoder.decode(((ResponseFacade) servletResponse).getHeader("errorMsg"), "UTF-8")));
outParam=JSON.toJSONString(params);
}catch(Exception e) {
}//记录出参响应体
if (params.size() < 2) {
outParam= outParam + newString(responseWrapper.toByteArray(), responseWrapper.getCharacterEncoding());
}
log.info("出参:" +outParam);
ThreadContext.clearAll();
}
@Overridepublic void init(FilterConfig filterConfig) throwsServletException {
}
@Overridepublic voiddestroy() {
}
}