Spring Cloud Gateway 2.x 获取body中的数据并缓存在请求中

场景

因为http请求中的body,读取过一次后就无法重新再读,但是我们希望网关项目中可以在所有filter中共享body中的内容。

写法


import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Component
@Slf4j
public class CacheBodyParamsFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (ParamsUtil.logBody(exchange)) {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        byte[] bytes = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(bytes);
                        DataBufferUtils.release(dataBuffer);
                        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                            DataBuffer buffer =  exchange.getResponse().bufferFactory().wrap(bytes);
                            DataBufferUtils.retain(buffer);
                            return Mono.just(buffer);
                        });
                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                        ServerWebExchange mutatedExchange = exchange.mutate().request(mutatedRequest).build();
                        return ServerRequest.create(mutatedExchange, HandlerStrategies.withDefaults().messageReaders())
                                .bodyToMono(String.class)
                                .doOnNext(objectValue -> {
                                    //在此处,将body中的params值获取到,并存放在本次请求的attributes属性中,这样就可以在本次请求中的所有地方进行使用了                            

                                    mutatedExchange.getAttributes().put(CommonConstant.PARAMS, ParamsUtil.buildParams(mutatedRequest,objectValue));
                                                                    }).then(chain.filter(mutatedExchange));
                    });
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

猜你喜欢

转载自blog.csdn.net/cainiao1412/article/details/109159139