如何使用ReadBodyPredicateFactory缓存有效载荷数据

时间:2019-05-07 12:23:21

标签: spring cloud gateway

我有spring boot微服务,并使用招摇发送大型Payoad。在服务器上,我只能得到15000个字符,并且不能读取重设2000个字符。

您能否告诉我如何使用ReadBodyPredicateFactory来缓存正文消息文本。

我正在使用springcloudgateway并添加了过滤器。在apply方法的过滤器中,我尝试使用读取有效负载json       DefaultServerRequest serverRequest =新的DefaultServerRequest(交换);       正文= serverRequest.bodyToMono(String.class).toFuture()。get();

有时会挂起。

我尝试过Flux,然后只收到一半信息         助焊剂主体= request.getBody();

    body.subscribe(buffer -> {

        try {
            System.out.println("byte count:" + 
           buffer.readableByteCount());
            byte[] bytes = new byte[buffer.readableByteCount()];
            buffer.read(bytes);
            DataBufferUtils.release(buffer);
            String bodyString = new String(bytes, StandardCharsets.UTF_8);
            sb.append(bodyString);
        } catch (Exception e) {
            e.printStackTrace();
        }

Thx

1 个答案:

答案 0 :(得分:1)

最近,我在应用程序中也需要类似的东西,我发现可以通过ServerWebExchangeUtils

中的Spring Cloud Gateway内置缓存来实现

在某些业务案例中使用请求内容的过滤器之前,我创建了一个只强制内容缓存的过滤器:

@Component
class CachingRequestBodyFilter extends AbstractGatewayFilterFactory<CachingRequestBodyFilter.Config> {

    public CachingRequestBodyFilter() {
        super(Config.class);
    }

    public GatewayFilter apply(final Config config) {
        return (exchange, chain) -> ServerWebExchangeUtils.cacheRequestBody(exchange,
            (serverHttpRequest) -> chain.filter(exchange.mutate().request(serverHttpRequest).build()));
    }

    public static class Config {
    }
}

在随后的任何过滤器中,我们可以提取请求主体的内容,如下所示:

// some ReadRequestBodyFilter filter

public GatewayFilter apply(final Config config) {
    return (exchange, chain) -> {
        final var cachedBody = new StringBuilder();
        final var cachedBodyAttribute = exchange.getAttribute(CACHED_REQUEST_BODY_ATTR);
        if (!(cachedBodyAttribute instanceof DataBuffer)) {
            // caching gone wrong error handling
        }
        final var dataBuffer = (DataBuffer) cachedBodyAttribute;
        cachedBody.append(StandardCharsets.UTF_8.decode(dataBuffer.asByteBuffer()).toString());
        final var bodyAsJson = cachedBody.toString();

        // some processing

        return chain.filter(exchange);
    };
}

然后,网关配置将如下所示:

spring:
  cloud:
    gateway:
      routes:
        - [...]
          filters:
            - CachingRequestBodyFilter
            - ReadRequestBodyFilter