feat: aos-web 增加body 重复读取过滤器

This commit is contained in:
wyl
2022-11-09 00:22:00 +08:00
parent 6a70e30233
commit 23bf4b8024
10 changed files with 305 additions and 1 deletions
+4
View File
@@ -29,5 +29,9 @@
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,87 @@
package com.aos.common.copy;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
/**
* @author: wangyl
* @date: 2022/11/6
* @description: 拷贝
*/
public class AosBeanUtils extends BeanUtils {
/**
* list拷贝
*
* @param sources 源列表
* @param target 拷贝到的目标列表类
* @return java.util.List<T>
* @Date 2021/8/16 0:11
* @Author hz21056617
* @Version V1.0
*/
public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target) {
return copyListProperties(sources, target, null);
}
/**
* list拷贝 可处理数据
*
* @param sources 源列表
* @param target 拷贝到的目标列表类
* @param callBack 数据处理方式
* @return java.util.List<T>
* @Date 2021/8/16 0:11
* @Author hz21056617
* @Version V1.0
*/
public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, BiConsumer<S, T> callBack) {
List<T> list = new ArrayList<>(sources.size());
for (S source : sources) {
T t = target.get();
copyProperties(source, t);
if (callBack != null) {
callBack.accept(source, t);
}
list.add(t);
}
return list;
}
/**
* 对象拷贝
*
* @param sources
* @param target
* @return T
* @Date 2022/11/6
* @Author wangyl
*/
public static <S, T> T copyProperties(S sources, Supplier<T> target) {
T t = target.get();
copyProperties(sources, t);
return t;
}
/**
* 对象拷贝
*
* @param sources
* @param target
* @return T
* @Date 2022/11/6
* @Author wangyl
*/
public static <S, T> T copyProperties(S sources, Supplier<T> target, BiConsumer<S, T> callBack) {
T t = target.get();
copyProperties(sources, t);
if (callBack != null) {
callBack.accept(sources, t);
}
return t;
}
}
+5
View File
@@ -39,6 +39,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.aos</groupId>
<artifactId>aos-web</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
@@ -70,7 +70,7 @@ public class SwaggerConfig implements ImportBeanDefinitionRegistrar {
*/
private ApiInfo apiInfo(String applicationName) {
return new ApiInfoBuilder()
.title(applicationName + "api列表")
.title(applicationName + "-api列表")
.description("aos系统api")
.version("1.0")
.build();
+12
View File
@@ -35,5 +35,17 @@
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,32 @@
package com.aos.web.conf;
import com.aos.web.filter.BodyRepeatReaderHttpServletFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author: wangyl
* @date: 2022/7/26
* @description: mybatis-plus配置
*/
@Configuration
public class AosWebConf {
@Bean
public FilterRegistrationBean<BodyRepeatReaderHttpServletFilter> registerLoginCheckFilter(BodyRepeatReaderHttpServletFilter requireLoginFilter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(requireLoginFilter);
registrationBean.addUrlPatterns("/*");
registrationBean.setName("bodyRepeatReaderHttpServletFilter");
registrationBean.setOrder(0);
return registrationBean;
}
@Bean
public BodyRepeatReaderHttpServletFilter bodyRepeatReaderHttpServletFilter()
{
return new BodyRepeatReaderHttpServletFilter();
}
}
@@ -0,0 +1,34 @@
package com.aos.web.filter;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author: wangyl
* @date: 2022/11/7
* @description: http包装器,解决流只能被消费一次问题
*/
@Slf4j
public class BodyRepeatReaderHttpServletFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
if (log.isDebugEnabled()) {
log.debug("BodyRepeatReaderHttpServletFilter init");
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
ServletRequest requestWrapper = new BodyRepeatReaderHttpServletRequestWrapper(httpServletRequest);
chain.doFilter(requestWrapper, response);
return;
}
chain.doFilter(request, response);
}
}
@@ -0,0 +1,78 @@
package com.aos.web.filter;
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.util.ArrayList;
import java.util.List;
/**
* BodyReaderHttpServletRequestWrapper
*
* @author luoyongchun
* @date 2019/07/02
*/
public class BodyRepeatReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
protected String body;
public BodyRepeatReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = getBody(request);
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
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();
}
};
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
/**
* 获取body
*
* @param httpServletRequest
* @return
*/
public static String getBody(HttpServletRequest httpServletRequest) throws IOException {
List<String> lines = new ArrayList<>();
BufferedReader reader = new BufferedReader(new InputStreamReader(httpServletRequest.getInputStream()));
try {
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} finally {
reader.close();
}
return String.join("", lines);
}
}
@@ -0,0 +1,51 @@
package com.aos.web.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
/**
* @author: wangyl
* @date: 2022/11/6
* @description: 请求参数打印拦截器
*/
@Slf4j
public class RequestInterceptor implements HandlerInterceptor, WebMvcConfigurer {
private final static String TRACE_ID = "trace.id";
/**
* 放入拦截器
*
* @param registry
* @return void
* @Date 2022/11/6
* @Author wangyl
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(this);
WebMvcConfigurer.super.addInterceptors(registry);
}
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) {
String tracId = httpServletRequest.getHeader(TRACE_ID);
if (!StringUtils.hasLength(tracId)) {
tracId = UUID.randomUUID()
.toString();
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) {
}
}
@@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.aos.web.conf.AosWebConf