feat: aos-web 增加body 重复读取过滤器
This commit is contained in:
@@ -29,5 +29,9 @@
|
|||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.alibaba</groupId>
|
||||||
<artifactId>transmittable-thread-local</artifactId>
|
<artifactId>transmittable-thread-local</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-beans</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,11 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aos</groupId>
|
||||||
|
<artifactId>aos-web</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class SwaggerConfig implements ImportBeanDefinitionRegistrar {
|
|||||||
*/
|
*/
|
||||||
private ApiInfo apiInfo(String applicationName) {
|
private ApiInfo apiInfo(String applicationName) {
|
||||||
return new ApiInfoBuilder()
|
return new ApiInfoBuilder()
|
||||||
.title(applicationName + "api列表")
|
.title(applicationName + "-api列表")
|
||||||
.description("aos系统api")
|
.description("aos系统api")
|
||||||
.version("1.0")
|
.version("1.0")
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -35,5 +35,17 @@
|
|||||||
<groupId>com.github.xiaoymin</groupId>
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
<artifactId>knife4j-spring-ui</artifactId>
|
<artifactId>knife4j-spring-ui</artifactId>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
</project>
|
</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);
|
||||||
|
}
|
||||||
|
}
|
||||||
+78
@@ -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
|
||||||
Reference in New Issue
Block a user