Web客户端请求的简单日志记录转储?



我正在尝试使用SpringWebClient进行一些基本的REST API调用。我收到一个错误,指出请求格式不正确,但我无法确切说明原因。有没有办法轻松记录请求的内容(实际上,只是请求正文(?我在网上找到的一切都非常复杂。这是我所拥有的:

LinkedMultiValueMap params = new LinkedMultiValueMap();
params.add("app_id", getOneSignalAppId());
params.add("included_segments", inSegment);
params.add("content_available", true);
params.add("contents", new LinkedMultiValueMap() {{
add("en", inTitle);
}});
BodyInserters.MultipartInserter inserter = BodyInserters.fromMultipartData(params);
WebClient client = WebClient.builder()
.baseUrl("https://onesignal.com")
.defaultHeader(HttpHeaders.AUTHORIZATION, "Basic " + getOneSignalKey())
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.build();
Mono<NotificationResponse> result = client
.post()
.uri("/api/v1/notifications")
.body(inserter)
.retrieve()
.bodyToMono(NotificationResponse.class);

我只想要一个将插入到请求正文中的 JSON 字符串。

您可以围绕 JSON 编码器创建自己的包装器/代理类(假设您使用的是 JSON(,并在将序列化正文发送到管间之前对其进行拦截。

如果您的请求要发送 JSON。 具体而言,您将扩展Jackson2JsonEncoder(默认编码器(的encodeValue方法(如果是流数据,则encodeValues(。然后,您可以根据需要处理该数据,例如日志记录等。您甚至可以根据环境/配置文件有条件地执行此操作。

这个自定义日志记录编码器可以在创建WebClient时指定,方法是将其作为编解码器提供:

CustomBodyLoggingEncoder bodyLoggingEncoder = new CustomBodyLoggingEncoder();
WebClient.builder()
.codecs(clientDefaultCodecsConfigurer -> {
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(bodyLoggingEncoder);
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
})
...

我写了一篇关于这个的博客文章。您也许能够找到多部分数据的编码器并应用类似的原则

为了完整起见,编码器可能如下所示:

public class CustomBodyLoggingEncoder extends Jackson2JsonEncoder {
@Override
public DataBuffer encodeValue(final Object value, final DataBufferFactory bufferFactory,
final ResolvableType valueType, @Nullable final MimeType mimeType, @Nullable final Map<String, Object> hints) {
// Encode/Serialize data to JSON
final DataBuffer data = super.encodeValue(value, bufferFactory, valueType, mimeType, hints);
// This is your code:
SomethingAmazing.doItWithThisData(extractBytes(data));
// Return the data as normal
return data;
}
private byte[] extractBytes(final DataBuffer data) {
final byte[] bytes = new byte[data.readableByteCount()];
data.read(bytes);
// We've copied the data above to our array, but must reset the buffer for actual usage
data.readPosition(0);
return bytes;
}
}

希望以某种方式有所帮助!

最新更新