Commit 8e21b5200a113c5626b2daa3f822e3d22af11666

Authored by YunaiV
1 parent cb094596

实现 request body 重复读取的功能

ruoyi-common/src/main/java/com/ruoyi/common/config/FilterConfig.java
@@ -44,15 +44,4 @@ public class FilterConfig { @@ -44,15 +44,4 @@ public class FilterConfig {
44 return registration; 44 return registration;
45 } 45 }
46 46
47 - @SuppressWarnings({"rawtypes", "unchecked"})  
48 - @Bean  
49 - public FilterRegistrationBean someFilterRegistration() {  
50 - FilterRegistrationBean registration = new FilterRegistrationBean();  
51 - registration.setFilter(new RepeatableFilter());  
52 - registration.addUrlPatterns("/*");  
53 - registration.setName("repeatableFilter");  
54 - registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);  
55 - return registration;  
56 - }  
57 -  
58 } 47 }
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java deleted
1 -package com.ruoyi.common.filter;  
2 -  
3 -import java.io.IOException;  
4 -import javax.servlet.Filter;  
5 -import javax.servlet.FilterChain;  
6 -import javax.servlet.FilterConfig;  
7 -import javax.servlet.ServletException;  
8 -import javax.servlet.ServletRequest;  
9 -import javax.servlet.ServletResponse;  
10 -import javax.servlet.http.HttpServletRequest;  
11 -  
12 -import org.springframework.http.MediaType;  
13 -import com.ruoyi.common.utils.StringUtils;  
14 -  
15 -/**  
16 - * Repeatable 过滤器  
17 - *  
18 - * @author ruoyi  
19 - */  
20 -public class RepeatableFilter implements Filter {  
21 - @Override  
22 - public void init(FilterConfig filterConfig) throws ServletException {  
23 -  
24 - }  
25 -  
26 - @Override  
27 - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  
28 - throws IOException, ServletException {  
29 - ServletRequest requestWrapper = null;  
30 - if (request instanceof HttpServletRequest  
31 - && StringUtils.equalsAnyIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {  
32 - requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);  
33 - }  
34 - if (null == requestWrapper) {  
35 - chain.doFilter(request, response);  
36 - } else {  
37 - chain.doFilter(requestWrapper, response);  
38 - }  
39 - }  
40 -  
41 - @Override  
42 - public void destroy() {  
43 -  
44 - }  
45 -}  
ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java deleted
1 -package com.ruoyi.common.filter;  
2 -  
3 -import java.io.BufferedReader;  
4 -import java.io.ByteArrayInputStream;  
5 -import java.io.IOException;  
6 -import java.io.InputStreamReader;  
7 -import javax.servlet.ReadListener;  
8 -import javax.servlet.ServletInputStream;  
9 -import javax.servlet.ServletResponse;  
10 -import javax.servlet.http.HttpServletRequest;  
11 -import javax.servlet.http.HttpServletRequestWrapper;  
12 -  
13 -import com.ruoyi.common.utils.http.HttpHelper;  
14 -  
15 -/**  
16 - * 构建可重复读取inputStream的request  
17 - *  
18 - * @author ruoyi  
19 - */  
20 -public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {  
21 - private final byte[] body;  
22 -  
23 - public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {  
24 - super(request);  
25 - request.setCharacterEncoding("UTF-8");  
26 - response.setCharacterEncoding("UTF-8");  
27 -  
28 - body = HttpHelper.getBodyString(request).getBytes("UTF-8");  
29 - }  
30 -  
31 - @Override  
32 - public BufferedReader getReader() throws IOException {  
33 - return new BufferedReader(new InputStreamReader(getInputStream()));  
34 - }  
35 -  
36 - @Override  
37 - public ServletInputStream getInputStream() throws IOException {  
38 -  
39 - final ByteArrayInputStream bais = new ByteArrayInputStream(body);  
40 -  
41 - return new ServletInputStream() {  
42 -  
43 - @Override  
44 - public int read() throws IOException {  
45 - return bais.read();  
46 - }  
47 -  
48 - @Override  
49 - public boolean isFinished() {  
50 - return false;  
51 - }  
52 -  
53 - @Override  
54 - public boolean isReady() {  
55 - return false;  
56 - }  
57 -  
58 - @Override  
59 - public void setReadListener(ReadListener readListener) {  
60 -  
61 - }  
62 - };  
63 - }  
64 -}  
src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
1 package cn.iocoder.dashboard.framework.web.config; 1 package cn.iocoder.dashboard.framework.web.config;
2 2
  3 +import cn.iocoder.dashboard.framework.web.core.filter.RequestBodyCacheFilter;
3 import org.springframework.boot.context.properties.EnableConfigurationProperties; 4 import org.springframework.boot.context.properties.EnableConfigurationProperties;
4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.Configuration;
@@ -50,4 +51,13 @@ public class WebConfiguration implements WebMvcConfigurer { @@ -50,4 +51,13 @@ public class WebConfiguration implements WebMvcConfigurer {
50 return new CorsFilter(source); 51 return new CorsFilter(source);
51 } 52 }
52 53
  54 + /**
  55 + * 创建 RequestBodyCacheFilter Bean,可重复读取请求内容
  56 + */
  57 + @Bean
  58 + @Order(Integer.MIN_VALUE)
  59 + public RequestBodyCacheFilter requestBodyCacheFilter() {
  60 + return new RequestBodyCacheFilter();
  61 + }
  62 +
53 } 63 }
src/main/java/cn/iocoder/dashboard/framework/web/core/filter/RequestBodyCacheFilter.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.web.core.filter;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import org.springframework.http.MediaType;
  5 +import org.springframework.web.filter.OncePerRequestFilter;
  6 +import org.springframework.web.util.ContentCachingRequestWrapper;
  7 +
  8 +import javax.servlet.FilterChain;
  9 +import javax.servlet.ServletException;
  10 +import javax.servlet.http.HttpServletRequest;
  11 +import javax.servlet.http.HttpServletResponse;
  12 +import java.io.IOException;
  13 +
  14 +/**
  15 + * Request Body 缓存 Filter,实现它的可重复读取
  16 + *
  17 + * 基于 Spring 提供的 {@link org.springframework.web.util.ContentCachingRequestWrapper} 实现
  18 + *
  19 + * @author 芋道源码
  20 + */
  21 +public class RequestBodyCacheFilter extends OncePerRequestFilter {
  22 +
  23 + @Override
  24 + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  25 + throws IOException, ServletException {
  26 + filterChain.doFilter(new ContentCachingRequestWrapper(request), response);
  27 + }
  28 +
  29 + @Override
  30 + protected boolean shouldNotFilter(HttpServletRequest request) {
  31 + // 只处理 json 请求内容
  32 + return !StrUtil.startWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE);
  33 + }
  34 +
  35 +}