gpt4 book ai didi

java - WebClient - 如何获取请求正文?

转载 作者:行者123 更新时间:2023-12-02 23:40:21 33 4
gpt4 key购买 nike

我已经开始使用 WebClient,并使用过滤器方法添加请求/响应日志记录:

WebClient.builder()
.baseUrl(properties.getEndpoint())
.filter((request, next) -> {
// logging
request.body()
})
.build();

我可以访问 url、http 方法、 header ,但在获取原始请求正文时遇到问题 body()请求方法返回BodyInserter ( BodyInserter<?, ? super ClientHttpRequest> body() .

如何转换BodyInserterString请求主体的表示?或者,如何正确记录整个请求/响应,同时还能够散列其中的潜在凭据?

最佳答案

尝试了所有答案,但其中一些不符合我的需求或根本不起作用。根据此答案编写了我自己的解决方案来拦截请求/响应主体并记录它们。

@Slf4j
@Component
public class LoggingCustomizer implements WebClientCustomizer {

@Override public void customize(WebClient.Builder webClientBuilder) {
webClientBuilder.filter((request, next) -> {
logRequest(request);
return next
.exchange(interceptBody(request))
.doOnNext(this::logResponse)
.map(this::interceptBody);
});
}

private ClientRequest interceptBody(ClientRequest request) {
return ClientRequest.from(request)
.body((outputMessage, context) -> request.body().insert(new ClientHttpRequestDecorator(outputMessage) {
@Override public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
return super.writeWith(Mono.from(body)
.doOnNext(dataBuffer -> logRequestBody(dataBuffer)));
}
}, context))
.build();
}

private ClientResponse interceptBody(ClientResponse response) {
return response.mutate()
.body(data -> data.doOnNext(this::logResponseBody))
.build();
}

private void logRequest(ClientRequest request) {
log.debug("DOWNSTREAM REQUEST: METHOD {}, URI: {}, HEADERS: {}", request.method(), request.url(), request.headers());
}

private void logRequestBody(DataBuffer dataBuffer) {
log.debug("DOWNSTREAM REQUEST: BODY: {}", dataBuffer.toString(StandardCharsets.UTF_8));
}

private void logResponse(ClientResponse response) {
log.debug("DOWNSTREAM RESPONSE: STATUS: {}, HEADERS: {}", response.rawStatusCode(), response.headers().asHttpHeaders());
}

private void logResponseBody(DataBuffer dataBuffer) {
log.debug("DOWNSTREAM RESPONSE: BODY: {}", dataBuffer.toString(StandardCharsets.UTF_8));
}

}

更新:使用reactor.netty.http.client.HttpClient添加了要记录的代码片段(首选解决方案)

@Slf4j
@Component
public class LoggingCustomizer implements WebClientCustomizer {

@Override public void customize(WebClient.Builder webClientBuilder) {
HttpClient httpClient = HttpClient.create()
.doOnRequest((httpClientRequest, connection) -> connection.addHandlerFirst(new LoggingHandler()));
webClientBuilder.clientConnector(new ReactorClientHttpConnector(httpClient));
}

private static class LoggingHandler extends ChannelDuplexHandler {

@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (msg instanceof FullHttpRequest request) {
log.debug("DOWNSTREAM REQUEST: METHOD: {}, URI: {}, BODY: {}, HEADERS: {}",
request.method(), request.uri(), request.content().toString(defaultCharset()), request.headers());
} else if (msg instanceof HttpRequest request) {
log.debug("DOWNSTREAM REQUEST: METHOD: {}, URI: {}, HEADERS: {}",
request.method(), request.uri(), request.headers());
} else if (msg instanceof FullHttpMessage message) {
log.debug("DOWNSTREAM REQUEST: BODY: {}",
message.content().toString(defaultCharset()));
}
super.write(ctx, msg, promise);
}

@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpResponse response) {
log.debug("DOWNSTREAM RESPONSE: STATUS: {}, BODY: {}, HEADERS: {}",
response.status().code(), response.content().toString(defaultCharset()), response.headers());
} else if (msg instanceof HttpResponse response) {
log.debug("DOWNSTREAM RESPONSE: STATUS: {}, HEADERS: {}",
response.status().code(), response.headers());
} else if (!(msg instanceof LastHttpContent) && msg instanceof HttpContent httpContent) {
log.debug("DOWNSTREAM RESPONSE: BODY: {}",
httpContent.content().toString(defaultCharset()));
}
super.channelRead(ctx, msg);
}
}

}

关于java - WebClient - 如何获取请求正文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57108631/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com