SpringCloud入门(十二):网关Gateway 获取Post请求体(Greenwich.SR2)

前言

在学习gateway的时候,使用全局过滤器GlobalFilter,来拦截请求的时候,网上的例子基本都是使用Get来完成的,很少使用Post来测试,导致在使用Post的时候,获取不到Body的内容。

实现方式

/**
 * 全局过滤器
 * 可拦截get、post等请求做逻辑处理
 * @author hero良
 * @className RequestGlobalFilter
 * @description
 */
@Slf4j
@Component
public class RequestGlobalFilter implements GlobalFilter, Ordered {

    /**
     *
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request= exchange.getRequest();

        String method = request.getMethodValue();

        if ("POST".equals(method)) {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        byte[] bytes = new byte[dataBuffer.readableByteCount()];
                        dataBuffer.read(bytes);
                        String bodyString = new String(bytes, StandardCharsets.UTF_8);
                        //TODO 得到Post请求的请求参数后,做你想做的事
                        log.info("bodyString====={}",bodyString);

                        exchange.getAttributes().put("POST_BODY",bodyString);
                        DataBufferUtils.release(dataBuffer);

                        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                            DataBuffer buffer = exchange.getResponse().bufferFactory()
                                    .wrap(bytes);
                            return Mono.just(buffer);
                        });
                        //下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }
                        };
                        //封装request,传给下一级
                        return chain.filter(exchange.mutate().request(mutatedRequest).build());
                    });
        } else if ("GET".equals(method)) {
            Map requestQueryParams = request.getQueryParams();
            //TODO 得到Get请求的请求参数后,做你想做的事

            return chain.filter(exchange);
        }
        return chain.filter(exchange);
    }

    /**
     * 执行顺序
     * @return
     */
    @Override
    public int getOrder() {
        return 1;
    }

}

用缓存的方式来获取

/**
 * @author hero良
 * @className CacheBodyGatewayFilter
 * @description
 * @date 2019/12/12 16:35
 */
@Component
public class CacheBodyGatewayFilter implements Ordered, GlobalFilter {

    public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (exchange.getRequest().getHeaders().getContentType() == null) {
            return chain.filter(exchange);
        } else {
            return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                        DataBufferUtils.retain(dataBuffer);
                        Flux<DataBuffer> cachedFlux = Flux
                                .defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));
                        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                exchange.getRequest()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                return cachedFlux;
                            }

                        };
                        exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, cachedFlux);

                        return chain.filter(exchange.mutate().request(mutatedRequest).build());
                    });
        }
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
/**
 * @author hero良
 * @className VerifyGatewayFilter
 * @description
 * @date 2019/12/12 16:36
 */
@Slf4j
@Component
public class VerifyGatewayFilter implements GlobalFilter, Ordered {

    public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        Object cacheBody = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY);
        if(cacheBody == null){
            return chain.filter(exchange);
        }
        String raw = toRaw((Flux<DataBuffer>)cacheBody);
        log.info(raw);
        return chain.filter(exchange);
    }

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

    private static String toRaw(Flux<DataBuffer> body) {
        AtomicReference<String> rawRef = new AtomicReference<>();
        body.subscribe(buffer -> {
            byte[] bytes = new byte[buffer.readableByteCount()];
            buffer.read(bytes);
            DataBufferUtils.release(buffer);
            rawRef.set(Strings.fromUTF8ByteArray(bytes));
        });
        return rawRef.get();
    }
}

两种方式都可以成功获取到请求体
在这里插入图片描述
SpringBoot版本为 2.1.7.RELEASE>
SpringCloud版本为 Greenwich.SR2

发布了34 篇原创文章 · 获赞 5 · 访问量 1702

猜你喜欢

转载自blog.csdn.net/zhengliangs/article/details/103566531