fix(log): 修复 LogFilter 无效及无法获取请求、响应体参数的问题

This commit is contained in:
2025-12-30 22:47:54 +08:00
parent 4f8d7725e6
commit 8ce00d8892
8 changed files with 41 additions and 48 deletions

View File

@@ -125,7 +125,7 @@ public class LogAspect {
return false;
}
// 如果接口匹配排除列表,不记录日志
if (logProperties.isMatch(attributes.getRequest().getRequestURI())) {
if (logProperties.isMatchExcludeUri(attributes.getRequest().getRequestURI())) {
return false;
}
return logHandler.isRecord(targetMethod, targetClass);

View File

@@ -64,7 +64,6 @@ public class LogAutoConfiguration {
* 日志过滤器
*/
@Bean
@ConditionalOnMissingBean
public FilterRegistrationBean<LogFilter> logFilter() {
FilterRegistrationBean<LogFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new LogFilter(logProperties));

View File

@@ -51,40 +51,41 @@ public class LogFilter extends OncePerRequestFilter {
protected void doFilterInternal(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
if (!this.isFilter(request)) {
if (this.isNotFilter(request)) {
filterChain.doFilter(request, response);
return;
}
// 包装可重复读取请求及响应
boolean isExcludeUri = logProperties.isMatch(request.getRequestURI());
HttpServletRequest requestWrapper = (isExcludeUri || !this.isRequestWrapper(request))
? request
RepeatReadRequestWrapper wrappedRequest = request instanceof RepeatReadRequestWrapper wrapped
? wrapped
: new RepeatReadRequestWrapper(request);
HttpServletResponse responseWrapper = (isExcludeUri || !this.isResponseWrapper(response))
? response
RepeatReadResponseWrapper wrappedResponse = response instanceof RepeatReadResponseWrapper wrapped
? wrapped
: new RepeatReadResponseWrapper(response);
filterChain.doFilter(requestWrapper, responseWrapper);
filterChain.doFilter(wrappedRequest, wrappedResponse);
// 如果响应被包装了,复制缓存数据到原始响应
if (responseWrapper instanceof RepeatReadResponseWrapper wrappedResponse) {
wrappedResponse.copyBodyToResponse();
}
// 复制缓存数据到原始响应
wrappedResponse.copyBodyToResponse();
}
/**
* 是否过滤请求
* 是否过滤
*
* @param request 请求对象
* @return 是否过滤请求
* @return true: 不过滤; false: 过滤
*/
private boolean isFilter(HttpServletRequest request) {
private boolean isNotFilter(HttpServletRequest request) {
if (!isRequestValid(request)) {
return false;
return true;
}
// 不拦截 /error
ServerProperties serverProperties = SpringUtil.getBean(ServerProperties.class);
return !request.getRequestURI().equals(serverProperties.getError().getPath());
if (request.getRequestURI().equals(serverProperties.getError().getPath())) {
return true;
}
// 放行路径
return logProperties.isMatchExcludeUri(request.getRequestURI());
}
/**
@@ -101,24 +102,4 @@ public class LogFilter extends OncePerRequestFilter {
return false;
}
}
/**
* 是否需要包装输入流
*
* @param request 请求对象
* @return truefalse
*/
private boolean isRequestWrapper(HttpServletRequest request) {
return !(request instanceof RepeatReadRequestWrapper);
}
/**
* 是否需要包装输出流
*
* @param response 响应对象
* @return truefalse
*/
private boolean isResponseWrapper(HttpServletResponse response) {
return !(response instanceof RepeatReadResponseWrapper);
}
}

View File

@@ -21,6 +21,7 @@ import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.util.UriUtils;
import org.springframework.web.util.WebUtils;
import top.continew.starter.core.constant.StringConstants;
import top.continew.starter.core.wrapper.RepeatReadRequestWrapper;
import top.continew.starter.log.http.RecordableHttpRequest;
@@ -79,11 +80,17 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest
@Override
public String getBody() {
if (request instanceof RepeatReadRequestWrapper wrapper && !wrapper.isMultipartContent(request)) {
String body = JakartaServletUtil.getBody(request);
try {
RepeatReadRequestWrapper wrappedRequest = WebUtils
.getNativeRequest(request, RepeatReadRequestWrapper.class);
if (wrappedRequest == null || wrappedRequest.isMultipartContent(request)) {
return null;
}
String body = wrappedRequest.getContentAsString();
return JSONUtil.isTypeJSON(body) ? body : null;
} catch (Exception e) {
return null;
}
return null;
}
@Override

View File

@@ -18,6 +18,7 @@ package top.continew.starter.log.http.servlet;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.util.WebUtils;
import top.continew.starter.core.util.ServletUtils;
import top.continew.starter.core.wrapper.RepeatReadResponseWrapper;
import top.continew.starter.log.http.RecordableHttpResponse;
@@ -54,11 +55,17 @@ public final class RecordableServletHttpResponse implements RecordableHttpRespon
@Override
public String getBody() {
if (response instanceof RepeatReadResponseWrapper wrapper && !wrapper.isStreamingResponse()) {
String body = wrapper.getResponseContent();
try {
RepeatReadResponseWrapper wrappedResponse = WebUtils
.getNativeResponse(response, RepeatReadResponseWrapper.class);
if (wrappedResponse == null || wrappedResponse.isStreamingResponse()) {
return null;
}
String body = wrappedResponse.getResponseContent();
return JSONUtil.isTypeJSON(body) ? body : null;
} catch (Exception e) {
return null;
}
return null;
}
@Override

View File

@@ -92,9 +92,9 @@ public class LogProperties {
* 是否匹配放行路由
*
* @param uri 请求 URI
* @return 是否匹配
* @return true: 匹配; false: 不匹配
*/
public boolean isMatch(String uri) {
public boolean isMatchExcludeUri(String uri) {
return this.getExcludePatterns().stream().anyMatch(pattern -> SpringWebUtils.isMatch(uri, pattern));
}
}

View File

@@ -96,7 +96,7 @@ public class AccessLogUtils {
*/
public static boolean exclusionPath(LogProperties properties, String path) {
// 放行路由配置的排除检查
return properties.isMatch(path) || RESOURCE_PATH.stream()
return properties.isMatchExcludeUri(path) || RESOURCE_PATH.stream()
.anyMatch(resourcePath -> SpringWebUtils.isMatchAnt(path, resourcePath));
}

View File

@@ -70,7 +70,6 @@ public class LogAutoConfiguration implements WebMvcConfigurer {
* 日志过滤器
*/
@Bean
@ConditionalOnMissingBean
public FilterRegistrationBean<LogFilter> logFilter() {
FilterRegistrationBean<LogFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new LogFilter(logProperties));