如何在 WebFilter 上配置 Spring DataBuffer 大小

Posted

技术标签:

【中文标题】如何在 WebFilter 上配置 Spring DataBuffer 大小【英文标题】:How to configure Spring DataBuffer size on WebFilter 【发布时间】:2020-04-05 04:07:11 【问题描述】:

我从客户端获取了一个 gzip 压缩的内容,我需要在它到达控制器之前对其进行解压缩,否则我会遇到杰克逊解析异常。

我创建了一个 WebFilter 来包装请求并将正文映射到一个缩小的字节数组,如下所示:

  @Override
    public Flux<DataBuffer> getBody() 
      return request.getBody().map(requestDataBuffer -> 
        try 
          GZIPInputStream gzipInputStream = new GZIPInputStream(requestDataBuffer.asInputStream());
          StringWriter writer = new StringWriter();
          IOUtils.copy(gzipInputStream, writer, UTF_8);
          byte[] targetArray = writer.toString().getBytes();
          return new DefaultDataBufferFactory().wrap(targetArray);
        
        catch (IOException e) 
          LOG.error("failed to create gzip input stream. content-encoding is ", request.getHeaders().getFirst(CONTENT_ENCODING));
          return requestDataBuffer;
        
      );
    

但是,当请求正文太大时,数据缓冲区不包含所有数据,因此会出现流异常。

任何想法如何配置数据缓冲区或如何接受 gzip 压缩的内容?

【问题讨论】:

【参考方案1】:

我认为最好的方法是依赖 Netty 实现,并将服务器配置为使用 Netty 的支持。

您可以创建自定义 Reactor Netty 服务器的组件(或直接从 @Bean 方法返回 this 的新实例):

@Component
public class RequestInflateCustomizer implements NettyServerCustomizer 

    @Override
    public HttpServer apply(HttpServer httpServer) 
        return httpServer.tcpConfiguration(
                tcp -> tcp.doOnConnection(conn -> conn.addHandlerFirst(new HttpContentDecompressor())));
    


【讨论】:

类似的东西你可以在这里看到github.com/reactor/reactor-netty/blob/master/src/test/java/…

以上是关于如何在 WebFilter 上配置 Spring DataBuffer 大小的主要内容,如果未能解决你的问题,请参考以下文章

聊聊@WebServlet @WebFilter @WebListener 和 @ServletComponentScan

如何使 WebFilter 在非 WebFlux/非反应式 Spring Boot 应用程序中工作?

Spring WebFilter 映射

更改 Spring Security WebFilter 的顺序

Spring WebFlux添加WebFIlter以匹配特定路径

spring boot webfilter 顺序