首页 > 其他分享 >gateway过滤器获取请求参数

gateway过滤器获取请求参数

时间:2023-02-27 09:24:06浏览次数:40  
标签:return 请求 exchange springframework filter org 过滤器 import gateway

import com.alibaba.fastjson.JSON;
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.*;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

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

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String method = request.getMethodValue();
        if ("POST".equals(method)) {
            //如果body里空,这三行代码不能省
            DefaultDataBufferFactory defaultDataBufferFactory = new DefaultDataBufferFactory();
            DefaultDataBuffer defaultDataBuffer = defaultDataBufferFactory.allocateBuffer(0);
            Mono<DataBuffer> mono = Flux.from(exchange.getRequest().getBody().defaultIfEmpty(defaultDataBuffer)).collectList().filter(list -> true).map(list -> list.get(0).factory().join(list)).doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
            //读取后重新封装请求
            return mono.flatMap(dataBuffer -> {
                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                dataBuffer.read(bytes);
                DataBufferUtils.release(dataBuffer);
                String body = new String(bytes, StandardCharsets.UTF_8);
                exchange.getAttributes().put("MY_PAYLOAD", body);
                //这是必须要重新封装一个请求, 因为body只能读一次,下游将无法读取,真操蛋
                Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                    DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
                    return Mono.just(buffer);
                });
                ServerHttpRequest newRequest = new ServerHttpRequestDecorator(request) {
                    @Override
                    public Flux<DataBuffer> getBody() {
                        return cachedFlux;
                    }
                };
                return chain.filter(exchange.mutate().request(newRequest).build());
            });
        } else if ("GET".equals(method)) {
            if("GET".equals(method)){
                Map<String, String> params = new HashMap<>();
                request.getQueryParams().forEach((k,v)-> params.put(k, v.get(0)));
                exchange.getAttributes().put("MY_PAYLOAD", JSON.toJSONString(params));
            }
        }
        return chain.filter(exchange);
    }

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

}

标签:return,请求,exchange,springframework,filter,org,过滤器,import,gateway
From: https://www.cnblogs.com/z8080/p/17158536.html

相关文章