1.创建自定义过滤器
import com.jdcloud.apim.openapi.util.RequestWrapper;
import annotation.Order;import javax.servlet.*;
import java.io.IOException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
//将过滤器注册到springboot的启动项中,顺序为第一个。这里有两种方法
//方法一:通过注解的方式
@Order(1)
@WebFilter(filterName = "httpServletRequestFilter", urlPatterns = "/*")
public class RequestReplacedFilter implements Filter {@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {ServletRequest requestWrapper = null;
// logger.debug("复制InputStream流");if (request instanceof HttpServletRequest) {requestWrapper = new RequestWrapper((HttpServletRequest) request);}//获取request请求中的流,将取出来的字符串保存在缓存中,同时再将该字符串再次转换成流,然后把它放入到新request对象中。if (requestWrapper == null) {chain.doFilter(request, response);} else {chain.doFilter(requestWrapper, response);}}@Overridepublic void init(FilterConfig arg0) throws ServletException {}}//方法二:在springboot的启动类中,添加如下代码:@Beanpublic FilterRegistrationBean httpServletRequestReplacedRegistration() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new HttpServletRequestReplacedFilter());registration.addUrlPatterns("/*");registration.addInitParameter("paramName", "paramValue");registration.setName("httpServletRequestReplacedFilter");registration.setOrder(1);return registration;}
2.创建request请求的包装类,获取到body信息的同时,将该body信息在放入到新的request对象中,并返回。
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;public class RequestWrapper extends HttpServletRequestWrapper {private final byte[] body;public RequestWrapper(HttpServletRequest request) throws IOException {super(request);body = Reader(), "utf-8");}@Overridepublic BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream(),"utf-8"));}@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 listener) {}@Overridepublic int read() throws IOException {ad();}};}/*** 通过BufferedReader和字符编码集转换成byte数组* @param br* @param encoding* @return* @throws IOException*/private byte[] readBytes(BufferedReader br, String encoding) throws IOException {String str = null;StringBuilder sb=new StringBuilder();while ((str = br.readLine()) != null) {sb.append(str);}String().getBytes(Charset.forName(encoding));}
}
3.在日志的拦截器中,获取request中的body信息
public class LoggerInterceptor implements HandlerInterceptor {private static Logger LOGGER = Logger(LoggerInterceptor.class);//拦截器处理之前@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {if(method.equals(HttpGet.METHOD_NAME)||method.equals(HttpDelete.METHOD_NAME)){requestParamQueryString();}else if(method.equals(HttpPost.METHOD_NAME)||method.equals(HttpPatch.METHOD_NAME)||method.equals(HttpPut.METHOD_NAME)){/*** 对来自后台的请求统一进行日志处理*/RequestWrapper requestWrapper;if (request instanceof RequestWrapper) {// 签名处理过程 questWrapper = (RequestWrapper) request;requestParam=getBodyString(requestWrapper);LOGGER.info("请求Body: {} ", requestParam);// 签名处理过程 }}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {RequestWrapper requestWrapper;if (request instanceof RequestWrapper) {// 测试再次获取questWrapper = (RequestWrapper) request;LOGGER.info("请求Body: {} ", getBodyString(requestWrapper)); // 测试再次获取}}private String getBodyString(HttpServletRequest request) throws IOException {StringBuilder sb = new StringBuilder();InputStream inputStream = null;BufferedReader reader = null;try {inputStream = InputStream();reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));String line = "";while ((line = adLine()) != null) {sb.append(line);}} catch (IOException e) {e.printStackTrace();} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if (reader != null) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}String().trim();}
}
至此,通过以上两篇文章即可实现获取request中的参数,实现在生产环境中日志可追溯的场景。以上是个人项目中的总结,有更好的方法欢迎大家留言。
本文发布于:2024-01-29 02:52:58,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170646798512184.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |