可依据需要自行改写。
1.对立拦挡异样配置类。
import com.sun.org.apache.xml.internal.security.Init;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.servlet.http.HttpServletRequest;/** * @author : ZhangXiaoHui * @description : 对立异样拦挡 * @create : 2021/11/23 15:21 */@RestControllerAdvicepublic class BaseExceptionHandler { private static final com.sun.org.slf4j.internal.Logger LOG = com.sun.org.slf4j.internal.LoggerFactory.getLogger(Init.class); /** * 所有异样 * @param e 异样 * @return 后果 */ @ExceptionHandler(Exception.class) public String handleException(Exception e) { HttpServletRequest request = WebHttpUtil.getRequest(); LOG.error(e.getMessage(), e); if (request != null) { String header = WebHttpUtil.parseRequestHeaders(request); String param = WebHttpUtil.parseParams(request); String body = WebHttpUtil.parseBodyParams(request); String ip = WebHttpUtil.getIP(request); LOG.error("报错接口申请信息: \n" + "申请ip:[" + ip + "]\n" + "申请头:[" + header + "]\n" + "申请头参数:[" + param + "]\n" + "申请体参数:[" + body + "]\n"); } LOG.error(e.getMessage(), e); return "零碎异样"; }}
2.解决HttpServletRequest的输出流只能读取一次。
import org.springframework.stereotype.Component;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ReadListener;import javax.servlet.ServletException;import javax.servlet.ServletInputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;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.StandardCharsets;/** * @author : ZhangXiaoHui * @description : * @create : 2022/9/9 10:45 */@Component@WebFilter(filterName = "HttpServletRequestFilter", urlPatterns = "/")public class HttpServletRequestFilter implements Filter { @Override public void init(FilterConfig filterConfig) { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { ServletRequest requestWrapper = null; if (servletRequest instanceof HttpServletRequest) { requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest); } //获取申请中的流如何,将取出来的字符串,再次转换成流,而后把它放入到新request对象中 if (null == requestWrapper) { filterChain.doFilter(servletRequest, servletResponse); } else { filterChain.doFilter(requestWrapper, servletResponse); } } @Override public void destroy() { } /*** * HttpServletRequest 包装器 * 解决: request.getInputStream()只能读取一次的问题 * 指标: 流可反复读 */ public static class RequestWrapper extends HttpServletRequestWrapper { /** * 申请体 */ private final String body; public RequestWrapper(HttpServletRequest request) { super(request); // 将body数据存储起来 this.body = getBody(request); } /** * 获取申请体 * * @param request 申请 * @return 申请体 */ private String getBody(HttpServletRequest request) { return WebHttpUtil.parseBodyParams(request); } @Override public BufferedReader getReader() { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() { // 创立字节数组输出流 final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() { return byteArrayInputStream.read(); } }; } }}
3.Http工具类
import cn.hutool.core.util.StrUtil;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.nio.charset.StandardCharsets;import java.util.Enumeration;/** * web工具类 * * @author 晓辉 */public class WebHttpUtil { /** * 返回申请端的IP地址 */ public static String getIP(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); ip = checkIp(ip) ? ip : ( checkIp(ip = request.getHeader("Proxy-Client-IP")) ? ip : ( checkIp(ip = request.getHeader("WL-Proxy-Client-IP")) ? ip : request.getRemoteAddr())); return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; } private static boolean checkIp(String ip) { return !StrUtil.isEmpty(ip) && !"unknown".equalsIgnoreCase(ip); } public static HttpServletRequest getRequest() { ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (servletRequestAttributes == null) { return null; } else { return servletRequestAttributes.getRequest(); } } /** * 获取get 申请信息 * @param request 申请 * @return 后果 */ public static String parseParams (HttpServletRequest request) { StringBuilder stringBuilder = new StringBuilder(); Enumeration<String> parameterNames = request.getParameterNames(); while (parameterNames.hasMoreElements()) { String name = parameterNames.nextElement(); String value = request.getParameter(name); stringBuilder.append(name).append("=").append(value).append(";"); } return stringBuilder.toString(); } /** * post申请体参数 * @param request 申请 * @return 后果 */ public static String parseBodyParams (HttpServletRequest request) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = request.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); String line; while ((line = reader.readLine()) != 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(); } } } return sb.toString(); } /** * 申请头信息 * @param request 申请 * @return 后果 */ public static String parseRequestHeaders (HttpServletRequest request) { StringBuilder stringBuilder = new StringBuilder(); Enumeration<String> headerNames = request.getHeaderNames(); stringBuilder.append("URL:").append(request.getRequestURI()).append("\n"); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); String value = request.getHeader(name); stringBuilder.append(name).append("=").append(value).append(";").append("\n"); } return stringBuilder.toString(); }}
4.实现成果
测试接口
后果
5.上传文件须要在配置文件中设置(yml格局)。否则上传文件报错,具体起因没去理解。
6.适宜不须要全局拦挡所有申请,只显示异样的申请信息。
spring: mvc: hiddenmethod: filter: enabled: true