如何在 Spring WebClient 中拦截 http 流量?
Posted
技术标签:
【中文标题】如何在 Spring WebClient 中拦截 http 流量?【英文标题】:How to intercept http traffic in Spring WebClient? 【发布时间】:2019-11-21 02:10:49 【问题描述】: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】:数据由 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
【讨论】:
关于您的链接答案:存在同样的问题:在ExchangeFilterFunction
内部,正文已编码为 DTO,因此无法作为本机缓冲区访问。您能否添加一个示例,说明如何拦截响应缓冲区以将其写下来?
它在答案中;)它按预期打印 JSON
对于Jaxb2XmlDecoder
?如何从Publisher<DataBuffer> inputStream
获取数据缓冲区?
你可以把Publisher转成Mono/Flux(例子在org.springframework.http.codec.xml.XmlEventDecoder#decode),然后做同样的事情。
对不起,对于我的问题,您的答案按预期工作!传出请求记录为 json/xml 字符串。问题更多在于正确拦截响应。也许你也可以看看? ***.com/questions/57037543/…以上是关于如何在 Spring WebClient 中拦截 http 流量?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring 响应式 WebClient 中返回 Kotlin Coroutines Flow
如何在运行在 Tomcat 上的 Spring Web 应用程序中使用 Spring 的响应式 WebClient
如何在 Spring Webflux / WebClient 中设置事件循环池大小?