[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

 

posted @ 2020-10-13 09:14  Xiwi  阅读(846)  评论(0编辑  收藏  举报