Spring 如何使用WebClient压缩JSON请求正文?

Spring 如何使用WebClient压缩JSON请求正文?,spring,spring-boot,spring-webflux,Spring,Spring Boot,Spring Webflux,我需要使用WebClient执行POST,服务器要求压缩正文。我检查了之前提出的问题,但没有一个能帮助我理解需要做什么 我的代码如下所示: webClient.post() .bodyValue(requestBody) .retrieve() .bodyToMono(Response.class) 我想发送使用gzip压缩的requestBody。我们使用RestTemplate和一个定制的GZipFilter来实现这一点,但我现在不知道如何使用WebClient来实

我需要使用
WebClient
执行
POST
,服务器要求压缩正文。我检查了之前提出的问题,但没有一个能帮助我理解需要做什么

我的代码如下所示:

webClient.post()
    .bodyValue(requestBody)
    .retrieve()
    .bodyToMono(Response.class)

我想发送使用gzip压缩的
requestBody
。我们使用RestTemplate和一个定制的
GZipFilter
来实现这一点,但我现在不知道如何使用WebClient来实现

我已经实现了示例代码来帮助您解决这个问题。你需要清理这个,并适应你的需要,但我已经测试过了,它确实有效

第一步是实现
编码器
,其中
是要编码的对象的类型。在我的示例中,我使用的是JsonNode

public class GzipEncoder extends AbstractEncoder<JsonNode> {

    public GzipEncoder() {
        super(MediaType.APPLICATION_JSON);
    }

    @Override
    public boolean canEncode(ResolvableType elementType, MimeType mimeType) {
        return MediaType.APPLICATION_JSON.equalsTypeAndSubtype(mimeType) && elementType.isAssignableFrom(JsonNode.class);
    }

    @Override
    public Flux<DataBuffer> encode(Publisher<? extends JsonNode> inputStream, DataBufferFactory bufferFactory, ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
        return Flux.from(inputStream).map((JsonNode node) ->
                encodeValue(node, bufferFactory, elementType, mimeType, hints));
    }

    @Override
    public DataBuffer encodeValue(JsonNode node, DataBufferFactory bufferFactory, ResolvableType valueType, MimeType mimeType, Map<String, Object> hints) {
        return bufferFactory.wrap(gzip(node.toString()));
    }

    private byte[] gzip(String value) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) {
            gzipOutputStream.write(value.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return baos.toByteArray();
    }
}
现在创建您的
WebClient
,如下所示(我添加了wiretap以确认gzip正在工作)

现在,当我发布带有以下内容的JsonNode主体时,我可以看到使用gzip编码的请求

webclientGzip.post().uri(uri)
            .accept(MediaType.APPLICATION_JSON)
            .contentType(MediaType.APPLICATION_JSON)
            .body(Mono.just(body), JsonNode.class)

非常感谢你!在对我们的代码进行了微小的修改后,它工作了。
WebClient webclientGzip = WebClient.builder()
        .codecs(clientCodecConfigurer -> clientCodecConfigurer.customCodecs().register(new GzipHttpMessageWriter()))
        .clientConnector(new ReactorClientHttpConnector(HttpClient.create().wiretap(true)))
        .build();
webclientGzip.post().uri(uri)
            .accept(MediaType.APPLICATION_JSON)
            .contentType(MediaType.APPLICATION_JSON)
            .body(Mono.just(body), JsonNode.class)