如何在Spring WebClient中拦截HTTP通信?

时间:2019-07-11 11:06:47

标签: java spring spring-webflux spring-webclient

WebFilter请求从DTO转换为JSON字符串后,我该如何拦截?

我当然可以添加一个ExchangeFilterFunction,但是clientRequest.body()仅显示我的输入对象,而不显示转换后的json字符串:

WebClient.builder().defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).filter(logRequest()).build();

private ExchangeFilterFunction logRequest() {
    return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
        LOGGER.info(clientRequest.body()); //body is MyRequest.class
        return Mono.just(clientRequest);
    });
}

MyRequestDto dto;
client.post().uri(url).syncBody(dto).retrieve().bodyToMono(MyResponseDto.class).block();

因此,我正在寻找一种方法,将传出的请求从dto转换为json字符串后,对其进行拦截。

反之亦然,在之前拦截响应,然后将它们从json转换为dto。

1 个答案:

答案 0 :(得分:1)

JacksonEncoder将数据写为String,而不是写为DataBuffer中的字节。拦截请求的一种方法是重写JSON编码器,然后直接访问DataBuffer或将其解释为String

Consumer<ClientCodecConfigurer> consumer = configurer ->
        configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder() {
            @Override
            public Flux<DataBuffer> encode(Publisher<?> inputStream, DataBufferFactory bufferFactory, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
                return super.encode(inputStream, bufferFactory, elementType, mimeType, hints)
                        .doOnNext(dataBuffer -> System.out.println(StandardCharsets.UTF_8.decode(dataBuffer.asByteBuffer()).toString()));
            }
        });

WebClient webClient = WebClient.builder()
        .exchangeStrategies(ExchangeStrategies.builder().codecs(consumer).build())
        .build();

如果目的仅在于记录传出邮件正文,请参见以下问题:how to log Spring 5 WebClient call