建设部网站下载浙江网站建设公司地址
springboot过滤器、拦截器相关知识
request.getParameterNames()不会消耗HTTP请求的输入流。
当处理application/json或multipart/form-data(特别是包含文件上传时)等类型的请求体时,这些内容通常不会通过getParameter或getParameterNames等方法直接访问,因为这些方法主要用于处理URL编码的表单数据。需要通过getInputStream()或getReader()等方法来读取整个请求体,并将其解析为相应的数据结构(如JSON对象或MultipartFile列表)。调用getInputStream()、getReader()等来读取请求体时,读取后会被关闭或消耗,意味着你不能在同一个请求中再次调用这些方法(除非你使用了某种形式的缓存或包装机制)。
getParameterNames()和getParameter()等方法访问的是请求参数,而不是请求体本身,因此它们不会消耗请求体。
HTTP请求体在Servlet容器中通常只能被读取一次,因为ServletInputStream和BufferedReader(后者通常是通过HttpServletRequest.getReader()获得的)在读取数据后不会将读取位置重置回开始。这意味着一旦你读取了请求体,你就无法在同一个请求中再次读取它,除非你在第一次读取时就已经将内容存储起来(比如复制到一个字节数组或字符流中)。
示例:在拦截器中读取Json参数
Java配置文件
@Configuration
public class CustomWebMvcConfig implements WebMvcConfigurer { @Autowired private CustomInterceptor customInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(customInterceptor) .addPathPatterns("/**"); // 拦截所有请求,或根据需要调整 } @Bean public FilterRegistrationBean<FormDataToJsonFilter> formDataToJsonFilter() { FilterRegistrationBean<FormDataToJsonFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new FormDataToJsonFilter()); registrationBean.addUrlPatterns("/*"); // 拦截所有请求 return registrationBean; }
}
过滤器
public class FormDataToJsonFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;ServletRequest requestWrapper = new JsonParamRequestWrapper(httpServletRequest);filterChain.doFilter(requestWrapper, servletResponse);// } }
自定义的HttpServletRequestWrapper
这个包装类将允许读取请求体,并且不会阻止其他组件(如Controller)再次读取它。
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; public class JsonParamRequestWrapper extends HttpServletRequestWrapper { private final String body; public JsonParamRequestWrapper (HttpServletRequest request) throws IOException { super(request); StringBuilder stringBuilder = new StringBuilder(); BufferedReader bufferedReader = null; try { InputStream inputStream = request.getInputStream(); if (inputStream != null) { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); char[] charBuffer = new char[128]; int bytesRead = -1; while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { stringBuilder.append(charBuffer, 0, bytesRead); } } } finally { if (bufferedReader != null) { bufferedReader.close(); } } body = stringBuilder.toString(); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(body.getBytes()))); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); return new ServletInputStream() { @Override public boolean isFinished() { return byteArrayInputStream.available() == 0; } @Override public boolean isReady() { return true; } @Override public int read() throws IOException { return byteArrayInputStream.read(); } }; } // Getter for the body (if needed) public String getBody() { return this.body; }
}
拦截器
@Component
public class CustomInterceptor implements HandlerInterceptor { private final RestTemplate restTemplate = new RestTemplate(); private final ObjectMapper objectMapper = new ObjectMapper(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if ("POST".equalsIgnoreCase(request.getMethod())) { JsonParamRequestWrapper requestWrapper = new JsonParamRequestWrapper(request);String body = requestWrapper.getRequestBody();logger.info("请求体:" + body);String sign = "";String data = "";// 进行验签逻辑boolean isValid = verifySignature(sign, data);if (!isValid) {response.setStatus(HttpServletResponse.SC_FORBIDDEN);return false;}} // 继续执行下一个拦截器或目标处理器 return true; } // 验签方法 private boolean validateSignature(String body) { // 验签逻辑 return true; } }