1

我从客户端得到一个 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;
        }
      });
    }

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

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

4

1 回答 1

2

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

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

@Component
public class RequestInflateCustomizer implements NettyServerCustomizer {

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

}
于 2019-12-12T08:59:33.740 回答