[JavaWeb] SpringBoot LogFilter获取 x-www-form-urlencoded/json 的请求参数
1 package com.xiwi.qa.common.filter; 2 3 import com.alibaba.fastjson.JSONObject; 4 import com.xiwi.qa.common.utils.http.BodyReaderHttpServletRequestWrapper; 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 import org.springframework.http.HttpHeaders; 8 import org.springframework.http.MediaType; 9 10 import javax.servlet.*; 11 import javax.servlet.annotation.WebFilter; 12 import javax.servlet.http.HttpServletRequest; 13 import java.io.IOException; 14 import java.util.Enumeration; 15 import java.util.LinkedHashMap; 16 17 /** 18 * file: LogFilter 19 * date: 2020-10-13 20 * time: 8:43 21 * explain: 获取接口请求参数 22 * author: Xiwi 23 */ 24 25 @WebFilter(urlPatterns = "/*", filterName = "logFilter") 26 public class LogFilter implements Filter { 27 28 private static final Logger logger = LoggerFactory.getLogger(LogFilter.class); 29 30 @Override 31 public void init(FilterConfig filterConfig) throws ServletException { 32 // logger.info("--------------logFilter 过滤器初始化------------"); 33 } 34 35 @Override 36 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 37 // 防止流读取一次后就没有了, 所以需要将流继续写出去 38 HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; 39 ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest); 40 printRequest(requestWrapper); 41 filterChain.doFilter(requestWrapper, servletResponse); 42 } 43 44 @Override 45 public void destroy() { 46 // logger.info("--------------过滤器销毁------------"); 47 } 48 49 private void printRequest(ServletRequest servletRequest) { 50 HttpServletRequest request = (HttpServletRequest) servletRequest; 51 String uri = request.getRequestURI(); 52 String protocol = request.getProtocol(); 53 String ip = request.getRemoteAddr(); 54 55 //获取请求头信息 56 JSONObject headerJson = new JSONObject(new LinkedHashMap<>()); 57 Enumeration<String> headerNames = request.getHeaderNames(); 58 //使用循环遍历请求头,并通过getHeader()方法获取一个指定名称的头字段 59 while (headerNames.hasMoreElements()){ 60 String headerName = headerNames.nextElement(); 61 headerJson.put(headerName, request.getHeader(headerName)); 62 } 63 String header = headerJson.toJSONString(); 64 65 66 String requestBody = ""; 67 String requestContentType = request.getHeader(HttpHeaders.CONTENT_TYPE); 68 if (requestContentType != null) { 69 // 拦截 x-www-form-urlencoded/json 请求的参数 70 if (requestContentType.startsWith(MediaType.APPLICATION_JSON_VALUE) || 71 requestContentType.startsWith(MediaType.APPLICATION_XML_VALUE) || 72 requestContentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) { 73 requestBody = getRequestBody(request); 74 logger.info("请求接口打印 url ==={}", uri); 75 logger.info("请求接口打印 urlParams ==={}", protocol); 76 logger.info("请求接口打印 参数 ==={}", requestBody); 77 logger.info("请求接口打印 请求头 ==={}", header); 78 logger.info("请求接口打印 IP ==={}", ip); 79 } 80 } 81 } 82 private String getRequestBody(HttpServletRequest request) { 83 int contentLength = request.getContentLength(); 84 if (contentLength <= 0) { 85 return ""; 86 } 87 try { 88 return request.getReader().readLine(); 89 } catch (IOException e) { 90 logger.error("获取请求体失败", e); 91 return ""; 92 } 93 } 94 }
1 package com.xiwi.qa.common.utils.http; 2 3 import javax.servlet.ReadListener; 4 import javax.servlet.ServletInputStream; 5 import javax.servlet.ServletRequest; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletRequestWrapper; 8 import java.io.*; 9 import java.nio.charset.Charset; 10 11 /** 12 * file: BodyReaderHttpServletRequestWrapper 13 * date: 2020-10-13 14 * time: 8:46 15 * explain: 16 * author: Xiwi 17 */ 18 public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { 19 private final byte[] body; 20 21 public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException { 22 super(request); 23 String sessionStream = getBodyString(request); 24 body = sessionStream.getBytes(Charset.forName("UTF-8")); 25 } 26 27 /** 28 * 获取请求Body 29 * 30 * @param request 31 * @return 32 */ 33 public String getBodyString(final ServletRequest request) { 34 StringBuilder sb = new StringBuilder(); 35 InputStream inputStream = null; 36 BufferedReader reader = null; 37 try { 38 inputStream = cloneInputStream(request.getInputStream()); 39 reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); 40 String line = ""; 41 while ((line = reader.readLine()) != null) { 42 sb.append(line); 43 } 44 } catch (IOException e) { 45 e.printStackTrace(); 46 } finally { 47 if (inputStream != null) { 48 try { 49 inputStream.close(); 50 } catch (IOException e) { 51 e.printStackTrace(); 52 } 53 } 54 if (reader != null) { 55 try { 56 reader.close(); 57 } catch (IOException e) { 58 e.printStackTrace(); 59 } 60 } 61 } 62 return sb.toString(); 63 } 64 65 /** 66 * Description: 复制输入流 67 * 68 * @param inputStream 69 * @return 70 */ 71 public InputStream cloneInputStream(ServletInputStream inputStream) { 72 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 73 byte[] buffer = new byte[1024]; 74 int len; 75 try { 76 while ((len = inputStream.read(buffer)) > -1) { 77 byteArrayOutputStream.write(buffer, 0, len); 78 } 79 byteArrayOutputStream.flush(); 80 } catch (IOException e) { 81 e.printStackTrace(); 82 } 83 InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); 84 return byteArrayInputStream; 85 } 86 87 @Override 88 public BufferedReader getReader() throws IOException { 89 return new BufferedReader(new InputStreamReader(getInputStream())); 90 } 91 92 @Override 93 public ServletInputStream getInputStream() throws IOException { 94 final ByteArrayInputStream bais = new ByteArrayInputStream(body); 95 96 return new ServletInputStream() { 97 98 @Override 99 public int read() throws IOException { 100 return bais.read(); 101 } 102 103 @Override 104 public boolean isFinished() { 105 return false; 106 } 107 108 @Override 109 public boolean isReady() { 110 return false; 111 } 112 113 @Override 114 public void setReadListener(ReadListener readListener) { 115 } 116 }; 117 } 118 }
最后把 logFilter 交给Spring管理;在启动类上 加上这一句
1 @ServletComponentScan(basePackages = "com.xiwi.qa.common.filter") //所扫描的包路径必须包含该Filter