首页 > 解决方案 > 当请求是多部分时,预请求过滤器(使用 webclient 进行 REST 调用)失败

问题描述

我有一个用例,其中某些请求网关需要调用休息端点(中间服务)并基于从响应中复制标头并将请求添加到最终下游服务(终端服务)。 流动: 图片

我在 Spring 云网关中实现了一个预请求过滤器。

虽然这适用于正常请求,但当我尝试使用此流程上传文件并出现以下错误时,它会失败:

2020-03-09 00:27:15.381 ERROR 32440 --- [ctor-http-nio-3] a.w.r.e.AbstractErrorWebExceptionHandler : [b5048ec0-5]  500 Server Error for HTTP POST "/upload"

reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ HTTP POST "/upload" [ExceptionHandlingWebHandler]
Stack trace:

或者

2020-03-09 00:11:38.247 ERROR 32440 --- [ctor-http-nio-3] a.w.r.e.AbstractErrorWebExceptionHandler : [b5048ec0-4]  500 Server Error for HTTP POST "/upload"

io.netty.handler.codec.EncoderException: java.lang.IllegalStateException: unexpected message type: PooledSlicedByteBuf
    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107) ~[netty-codec-4.1.45.Final.jar:4.1.45.Final]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ HTTP POST "/upload" [ExceptionHandlingWebHandler]
Stack trace:

示例 所有服务都使用 2.2.5.RELEASE 启动版本。

https://github.com/dhananjay12/spring-cloud/tree/master/spring-routing/spring-cloud-gateway-filters。README 文件中给出了详细信息。

网关应用程序.yml:

spring:
  cloud:
    gateway:
      routes:
        - id: end-service
          uri: http://localhost:8090
          predicates:
            - Path=/**
          filters:
            - name: RequestSize
              args:
                maxSize: 5000000
      default-filters:
        - MiddleServiceFilter
app:
  middle-service-url: http://localhost:8085/check

如果我删除过滤器,一切正常。通过多种方式尝试了 Webclient 初始化,WebClient.builder()WebClient.builder().clientConnector(new ReactorClientHttpConnector( HttpClient.newConnection().compress(true)))没有运气。

过滤器有什么特别需要做的吗?

标签: spring-cloudgatewayspring-cloud-gatewayreactor-nettyspring-webclient

解决方案


推荐阅读