一、需求分析
SpringCloud多服务项目环境,前端请求经过网关中转发到各个服务节点。日志中需要记录请求头中的部分参数、请求的body、响应状态及响应内容,并在请求头中新增一个标识。
二、代码实现
1. 装饰Request
@Component
public class RequestFilter implements GlobalFilter, Ordered {
/**
* 1.封装 HttpRequest,使 Request body 可以重复读取;
* 2.封装 HttpRequestHeader,添加requestId;
*/
@Override
public int getOrder() {
// 最高优先级的执行顺序
return HIGHEST_PRECEDENCE;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// Request.
ServerHttpRequest request = exchange.getRequest();
// 新建Header 添加 requestId.
String requestId = new SnowFlakeId().get();
request.mutate().headers(httpHeaders -> {
httpHeaders.set("requestId", requestId);
}).build();
if (Objects.requireNonNull(request.getMethod()).equals(HttpMethod.POST)) {
// body 为null, 不会执行里面的重分派.
DefaultDataBufferFactory defaultDataBufferFactory = new DefaultDataBufferFactory();
DefaultDataBuffer defaultDataBuffer = defaultDataBufferFactory.allocateBuffer(0);
//构建新数据流, 当body为空时,构建空流
Flux<DataBuffer> bodyDataBuffer = exchange.getRequest().getBody().defaultIfEmpty(defaultDataBuffer);
return DataBufferUtils.join(bodyDataBuffer)
.flatMap(dataBuffer -> {
// Request.
DataBuffer