【问题标题】:How to use ReadBodyPredicateFactory to cache payload data如何使用 ReadBodyPredicateFactory 缓存有效负载数据
【发布时间】:2019-09-25 02:46:01
【问题描述】:

我有 Spring Boot 微服务,并使用 swagger 发送大型有效负载。在服务器上我只得到 15000 个字符,并且重置 2000 个字符没有被读取。

如何使用 ReadBodyPredicateFactory 缓存正文消息文本?

我正在使用 springcloudgateway 并添加了过滤器。在应用方法的过滤器中,我尝试使用

读取有效负载 json
  DefaultServerRequest serverRequest = new DefaultServerRequest(exchange);
  body = 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();
        }

【问题讨论】:

    标签: spring cloud gateway


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2019-08-27
      • 2014-09-05
      • 2011-04-19
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      相关资源
      最近更新 更多