Я реализовал пример кода, чтобы помочь вам в этом. Вам нужно будет это исправить и адаптировать к вашим потребностям, но я проверил это, и оно работает.
Первый шаг - реализовать Encoder<T>
, где <T>
- это тип объекта, который вы используете. хочу кодировать. В моем примере я использую 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();
}
}
Затем вы также должны реализовать HttpMessageWriter
public class GzipHttpMessageWriter extends EncoderHttpMessageWriter {
public GzipHttpMessageWriter() {
super(new GzipEncoder());
}
@Override
public Mono<Void> write(Publisher inputStream, ResolvableType elementType, MediaType mediaType, ReactiveHttpOutputMessage message, Map hints) {
return super.write(inputStream, elementType, mediaType, updateContentEncoding(message), hints);
}
private ReactiveHttpOutputMessage updateContentEncoding(ReactiveHttpOutputMessage message) {
message.getHeaders().add("Content-Encoding", "gzip");
return message;
}
}
Теперь создайте свой WebClient
следующим образом (я добавил прослушку подтвердите, что gzip работает)
WebClient webclientGzip = WebClient.builder()
.codecs(clientCodecConfigurer -> clientCodecConfigurer.customCodecs().register(new GzipHttpMessageWriter()))
.clientConnector(new ReactorClientHttpConnector(HttpClient.create().wiretap(true)))
.build();
Теперь, когда я публикую тело JsonNode со следующим сообщением, я вижу, как выходит запрос, закодированный с помощью gzip
webclientGzip.post().uri(uri)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(body), JsonNode.class)