不多说 直接上代码
第一步
package com.xxx.init.webFilter;import com.alibaba.fastjson.JSONObject;
import com.xxx.api.constant.CommonConstant;
import com.xxx.api.entities.log.OperationLog;
import com.xxx.init.utils.JwtHelper;
import com.xxx.init.utils.RequestUtils;
import com.xxx.init.utils.WlUtils;
import com.xxx.init.webFilter.jsonWrapper.JsonParameterRequestWrapper;import com.xxx.init.webFilter.jsonWrapper.ResponseWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;/*** User:Json* Date: 2024/4/3* 日志操作**/
@WebFilter(urlPatterns = {"/*"}, filterName = "OperationLogFilter")
@Order(-100)
@Slf4j
public class OperationLogFilter implements Filter {@Value("${spring.application.name}")private String serviceName;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;if ("GET".equals(httpServletRequest.getMethod())) {chain.doFilter(request, response);return;}// 在请求到达 Servlet 前执行的逻辑boolean isDownload = false;// 检查响应头信息String contentDescription = httpServletRequest.getHeader("content-description");String contentTransferEncoding = httpServletRequest.getHeader("content-transfer-encoding");if (!StringUtils.isEmpty(contentDescription) &&!StringUtils.isEmpty(contentTransferEncoding)) {isDownload = true; // 设置为 true,表示需要下载}OperationLog operationLog = new OperationLog();operationLog.setOrg_id(0);operationLog.setTime(LocalDateTime.now());operationLog.setMethod(httpServletRequest.getMethod());operationLog.setRouter(httpServletRequest.getRequestURI());operationLog.setProtocol(httpServletRequest.getProtocol());operationLog.setIp(httpServletRequest.getRemoteAddr());operationLog.setService_name(serviceName);//获取请求类型为 Json的 数据 如果是form-data 类型的数据 目前没获取JsonParameterRequestWrapper jsonParameterRequestWrapper = null;if (WlUtils.isJsonReq(httpServletRequest)) {jsonParameterRequestWrapper = new JsonParameterRequestWrapper(httpServletRequest);operationLog.setRequest_data(getRequestJson(jsonParameterRequestWrapper));}ResponseWrapper responseWrapper = new ResponseWrapper(httpServletResponse);if (jsonParameterRequestWrapper == null) {chain.doFilter(request, responseWrapper);} else {chain.doFilter(jsonParameterRequestWrapper, responseWrapper);}String s = new String(responseWrapper.getContent(), "UTF-8");operationLog.setResponse_code(responseWrapper.getStatus());operationLog.setResponse_data(isDownload ? "文件下载" : s);// 在得到响应的数据之后,response的输出流中就无可用的数据,所以需要巴数据放回去ServletOutputStream outputStream = response.getOutputStream();outputStream.write(responseWrapper.getContent());outputStream.flush();outputStream.close();}private JSONObject getRequestJson(JsonParameterRequestWrapper jsonParameterRequestWrapper) throws IOException {String bodyMessage = jsonParameterRequestWrapper.getBodyMessage();JSONObject jsonObject = JSONObject.parseObject(bodyMessage);return jsonObject;}@Overridepublic void destroy() {}
}
第二步:
package com.xxx.init.webFilter.jsonWrapper;import com.xxx.init.utils.StreamUtil;
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;
/*** User:Json* Date: 2024/4/7**/
public class JsonParameterRequestWrapper extends HttpServletRequestWrapper {//用于保存读取body中数据private byte[] body;private String bodyMessage;public JsonParameterRequestWrapper(HttpServletRequest request) throws IOException {super(request);//读取请求的数据保存到本类当中body = StreamUtil.readBytes(request.getReader(), "UTF-8");bodyMessage = new String(body,"utf-8");}//覆盖(重写)父类的方法@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}//覆盖(重写)父类的方法@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(body);return new ServletInputStream() {@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}@Overridepublic int read() throws IOException {return bais.read();}};}/*** 获取body中的数据* @return*/public byte[] getBody() {return body;}/*** 把处理后的参数放到body里面* @param body*/public void setBody(byte[] body) {this.body = body;}public String getBodyMessage() {return bodyMessage;}
}
第三步
package com.xxx.init.webFilter.jsonWrapper;import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
import java.nio.charset.StandardCharsets;/*** User:Json* Date: 2024/4/7**/
public class ResponseWrapper extends HttpServletResponseWrapper {private ByteArrayOutputStream byteArrayOutputStream;private ServletOutputStream servletOutputStream;/*** Constructs a response adaptor wrapping the given response.* @param response The response to be wrapped* @throws IllegalArgumentException if the response is null*/public ResponseWrapper(HttpServletResponse response) throws IOException {super(response);byteArrayOutputStream = new ByteArrayOutputStream();servletOutputStream = new MyServletOutputStream(byteArrayOutputStream);}@Overridepublic ServletOutputStream getOutputStream() throws IOException {return servletOutputStream;}@Overridepublic PrintWriter getWriter() throws IOException {return new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, StandardCharsets.UTF_8));}@Overridepublic void flushBuffer() {if (servletOutputStream != null) {try {servletOutputStream.flush();} catch (IOException e) {e.printStackTrace();}}}public byte[] getContent() {flushBuffer();// response中的数据return byteArrayOutputStream.toByteArray();}class MyServletOutputStream extends ServletOutputStream {// 把response输出流中的数据写入字节流中private ByteArrayOutputStream byteArrayOutputStream;public MyServletOutputStream(ByteArrayOutputStream byteArrayOutputStream) {this.byteArrayOutputStream = byteArrayOutputStream;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setWriteListener(WriteListener listener) {}@Overridepublic void write(int b) throws IOException {byteArrayOutputStream.write(b);}}
}
第五步:
package com.xxx.init.utils;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/*** User:Json* Date: 2024/4/7**/
public class StreamUtil {public static byte[] readStream(InputStream stream,int length) throws IOException {byte[]streamData=null;List<Integer> lengths = new ArrayList<Integer>();List<byte[]> buffers = new ArrayList<byte[]>();int l = 0; int totalLength = 0; byte[] buffer = null; //while (totalLength < length && l != -1) { //buffer = new byte[length];l = stream.read(buffer);if (l != -1) {lengths.add(new Integer(l));buffers.add(buffer);totalLength+=l;}}if(totalLength==0) {return null;}l=0;streamData = new byte[totalLength];length =buffers.size();int blength=0;byte[] bbuffer=null;for (int i = 0; i < length; i++) {blength = ((Integer) lengths.get(i)).intValue();bbuffer = (byte[]) buffers.get(i);System.arraycopy(bbuffer, 0, streamData, l,blength);l=l+blength;}stream=null; lengths=null; buffers=null; buffer=null;return streamData;}public static byte[] readBytes(BufferedReader bufferedReader, String charset) throws IOException{StringBuffer sb = new StringBuffer();String s;while ((s = bufferedReader.readLine()) != null) {sb.append(s);}if(sb.length() == 0){return "".getBytes(charset);}return sb.toString().getBytes(charset);}}
第六步:
package com.xxx.init.utils;import javax.servlet.http.HttpServletRequest;/*** User:Json* Date: 2024/4/7**/
public class WlUtils {/*** 判断是否是JSON请求* @param request* @return*/public static Boolean isJsonReq(HttpServletRequest request){String header = request.getHeader("content-type");return header != null && header.toLowerCase().contains("json");}
}
测试
完美收工