我正在尝试使用Spring WebClient
进行一些基本的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字符串。
答案 0 :(得分:0)
您可以围绕JSON编码器创建自己的包装器/代理类(假设您使用的是JSON),并在将序列化的正文发送到插管之前对其进行拦截。
如果您的请求将发送JSON。
具体来说,您将扩展encodeValue
(默认编码器)的encodeValues
方法(或在流数据的情况下为Jackson2JsonEncoder
)。然后,您可以根据需要处理这些数据,例如日志记录等。甚至可以根据环境/配置文件有条件地进行处理。
可以在创建WebClient
时通过将其提供为编解码器来指定此自定义日志记录编码器:
CustomBodyLoggingEncoder bodyLoggingEncoder = new CustomBodyLoggingEncoder();
WebClient.builder()
.codecs(clientDefaultCodecsConfigurer -> {
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(bodyLoggingEncoder);
clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
})
...
我对此做了blog post。您也许可以找到用于Multipart数据的编码器并应用类似的原理
为完整起见,编码器可能看起来像这样:
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;
}
}
希望能有所帮助!