首页 > 解决方案 > 如何在 Spring WebClient / DataBuffer 中拦截 http 响应流量?

问题描述

如何WebClient在 XML 响应从字节转换为 DTO 之前拦截它们?

我尝试添加一个exchangeStrategy,但我如何转换DataBuffer为字符串,然后仍然调用该super.decode()方法?

ExchangeStrategies.builder().codecs((configurer) -> {
    configurer.defaultCodecs().jackson2JsonDecoder(new Jaxb2XmlDecoder() {
        @Override
        public Flux<Object> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
            //TODO how to log the response as string content? 
            return super.decode(inputStream, elementType, mimeType, hints);
        }
    }));

我成功如下,但我不知道这是否是正确的解决方案?尤其是在里面返回一个空集合flatMapInterable()感觉不对,但我没有找到另一种方法让它工作。

@Override
public Flux<Object> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
    return DataBufferUtils.join(inputStream)
            .flatMapIterable(buffer -> {
                try {
                    LOGGER.info(StandardCharsets.UTF_8.decode(buffer.asByteBuffer()).toString());
                    return Collections.emptyList();
                } finally {
                    DataBufferUtils.release(buffer);
                }
            })
            .map(arg -> super.decode(inputStream, elementType, mimeType, hints));
}

问题:map()由于我已经阅读了DataBuffer. 我怎么能读好几遍?

标签: javaspringspring-mvcspring-webclient

解决方案


到目前为止,我想出了以下解决方案。它有效,但我仍然愿意改进,因为我什至不知道我在这里是否正确地这样做。

@Override
public Flux<Object> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
    return DataBufferUtils.join(inputStream)
            .doOnNext(buf -> LOGGER.info(StandardCharsets.UTF_8.decode(buf.asByteBuffer()).toString()))
            .flatMapMany(buf -> super.decode(Mono.fromSupplier(() -> buf), elementType, mimeType, hints));
}

推荐阅读