This commit is contained in:
2025-09-11 01:11:21 +08:00
2 changed files with 58 additions and 32 deletions

View File

@ -20,6 +20,7 @@ import org.springframework.web.server.ServerWebExchangeDecorator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@ -64,7 +65,8 @@ public class LoggingGlobalFilter implements GlobalFilter, Ordered {
private static class CustomExchange extends ServerWebExchangeDecorator implements CustomExchangeInterface {
private final StringBuilder requestBody = new StringBuilder();
private String responseBody;
private final StringBuilder responseBodyBuilder = new StringBuilder();
public CustomExchange(ServerWebExchange delegate) {
@ -88,25 +90,31 @@ public class LoggingGlobalFilter implements GlobalFilter, Ordered {
};
}
@Override
public ServerHttpResponse getResponse() {
return new ServerHttpResponseDecorator(super.getResponse()) {
private final StringBuilder responseBodyBuilder = new StringBuilder();
ServerHttpResponse originalResponse = super.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
return new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
return super.writeWith(Flux.from(body)
.doOnNext(buffer -> {
DataBufferUtils.join(Flux.just(buffer))
.map(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
responseBody = new String(content, StandardCharsets.UTF_8);
return dataBuffer;
})
.subscribe();
}));
Flux<? extends DataBuffer> flux = (Flux<? extends DataBuffer>) body;
return super.writeWith(flux.doOnNext(dataBuffer -> {
// 复制数据以避免修改原始缓冲区
DataBuffer duplicate = dataBuffer.factory().allocateBuffer(dataBuffer.readableByteCount());
duplicate.write(dataBuffer);
// 读取数据内容用于日志记录
byte[] bytes = new byte[duplicate.readableByteCount()];
duplicate.read(bytes);
String bodyContent = new String(bytes, StandardCharsets.UTF_8);
responseBodyBuilder.append(bodyContent);
// 释放复制的缓冲区
DataBufferUtils.release(duplicate);
}));
}
return super.writeWith(body);
}
@ -120,7 +128,7 @@ public class LoggingGlobalFilter implements GlobalFilter, Ordered {
@Override
public String getResponseBody() {
return responseBody;
return responseBodyBuilder.toString();
}
}

View File

@ -23,6 +23,7 @@ import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@ -30,38 +31,46 @@ import java.util.List;
//@Configuration
public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
try {
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
HttpStatus statusCode = originalResponse.getStatusCode();
// 排除特定路径避免处理Swagger等静态资源
String path = exchange.getRequest().getURI().getPath();
if (path.contains("/v2/api-docs") ||
path.contains("/swagger") ||
path.contains("/webjars")) {
return chain.filter(exchange);
}
if (statusCode != HttpStatus.OK) {
return chain.filter(exchange);//降级处理返回数据
}
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
return super.writeWith(fluxBody.map(dataBuffer -> {
// 复制数据以避免修改原始缓冲区
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
// 合并多个流集合,解决返回体分段传输
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer buff = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[buff.readableByteCount()];
buff.read(content);
DataBufferUtils.release(buff);//释放掉内存
//排除Excel导出不是application/json不打印。若请求是上传图片则在最上面判断。
// 排除Excel导出不是application/json不打印。若请求是上传图片则在最上面判断。
MediaType contentType = originalResponse.getHeaders().getContentType();
if (!MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
if (contentType == null || !MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
return bufferFactory.wrap(content);
}
// 构建返回日志
String joinData = new String(content);
String joinData = new String(content, StandardCharsets.UTF_8);
String result = modifyBody(joinData);
List<Object> rspArgs = new ArrayList<>();
rspArgs.add(originalResponse.getStatusCode().value());
@ -69,8 +78,8 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
rspArgs.add(result);
log.info("<-- {} {}\n{}", rspArgs.toArray());
getDelegate().getHeaders().setContentLength(result.getBytes().length);
return bufferFactory.wrap(result.getBytes());
// 返回处理后的内容
return bufferFactory.wrap(result.getBytes(StandardCharsets.UTF_8));
}));
} else {
log.error("<-- {} 响应code异常", getStatusCode());
@ -88,14 +97,23 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
// 设置较低优先级,确保在其他过滤器之后执行
return Ordered.LOWEST_PRECEDENCE - 1;
}
//返回统一的JSON日期数据 2024-02-23 11:00 null转空字符串
private String modifyBody(String jsonStr){
JSONObject json = JSON.parseObject(jsonStr, Feature.AllowISO8601DateFormat);
JSONObject.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm";
return JSONObject.toJSONString(json, (ValueFilter) (object, name, value) -> value == null ? "" : value, SerializerFeature.WriteDateUseDateFormat);
if (jsonStr == null || jsonStr.isEmpty()) {
return jsonStr;
}
try {
JSONObject json = JSON.parseObject(jsonStr, Feature.AllowISO8601DateFormat);
JSONObject.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm";
return JSONObject.toJSONString(json, (ValueFilter) (object, name, value) -> value == null ? "" : value, SerializerFeature.WriteDateUseDateFormat);
} catch (Exception e) {
// 如果不是有效的JSON直接返回原始字符串
return jsonStr;
}
}
}