java—如何在控制台上显示作为有效负载传输的webclient的json主体?

ar7v8xwq  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(413)

我使用spring webclient,代码如下:

public String HttpCall() {

    Insurer insurer = new Insurer();
    insurer.setName(“Axa”);
    insurer.setId(“T-185785”);

    ClientResponse response = webclient.post()
        .uri("http://localhost:8080/process/insurer")
        .header(HttpHeaders.AUTHORIZATION, token)
        .accept(MediaType.APPLICATION_JSON)
        .bodyValue(insurer)
        .exchange()
        .block(Duration.ofMinutes(5))

    if (response.statusCode() == HttpStatus.OK) {
       return response.bodyToMono(String.class).block();
    } else
      // eventually, other code here;
    }
}

我需要的是在控制台上将有效负载显示为我身体的格式非常好的json(在我的代码片段中:pojo)
有人知道吗?
致以最诚挚的问候。

bfrts1fy

bfrts1fy1#

这可以通过实现 Jackson2JsonEncoder 记录请求主体的。
这篇博文对此进行了解释:https://andrew-flower.com/blog/webclient-body-logging.
构建webclient时,可以指定自定义编码器:

WebClient webClient = WebClient.builder()
                               .baseUrl(...)
                               .codecs(codecConfigurer -> {
                                    codecConfigurer.defaultCodecs().jackson2JsonEncoder(loggingEncoder);
                               })
                               ...
                               .build();

产生序列化字节的编码器示例如下:

public class LoggingJsonEncoder extends Jackson2JsonEncoder {
    private final Consumer<byte[]> payloadConsumer;

    public LoggingJsonEncoder(final Consumer<byte[]> payloadConsumer) {
        this.payloadConsumer = payloadConsumer;
    }

    @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);

        // Interception: Generate Signature and inject header into request
        bodyConsumer.accept(extractBytesAndReset(data));

        // Return the data as normal
        return data;
    }

    private byte[] extractBytesAndReset(final DataBuffer data) {
        final byte[] bytes = new byte[data.readableByteCount()];
        data.read(bytes);
        data.readPosition(0);
        return bytes;
    }
}

因此,您可以使用打印到stdout的使用者创建编码器,并在第一个代码片段中将其传递给webclient builder。

LoggingJsonEncoder loggingEncoder = new LoggingJsonEncoder(bytes -> System.out.print(new String(bytes)));

请记住,这将是缓慢的,因为它是同步读取整个序列化数据。所以只能在dev/debug模式下使用。

hlswsv35

hlswsv352#

打印json有多种方法。假设它是用于非生产和更多的调试。
我分享了一个使用jackson的例子(你可以使用任何你喜欢的库,也可以使用你选择的记录器,使用system.out.print只是为了演示。
你需要添加一个依赖项。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.0</version>
</dependency>

下面显示了一个简单的类来演示如何实现它。

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Mono;

public class MonoImpl {

    private static void testPrintInMono() throws JsonProcessingException {
        String test="{}";
       String atr = Mono.just(test).doOnNext(s->{
       JsonNode a = null;
       try {
            a = new ObjectMapper().readValue(s, JsonNode.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        a.toPrettyString();
        System.out.println(a.toPrettyString());
    }).block();

}

  private static void testPrintAfterUnBlock() throws JsonProcessingException {
      String test="{}";
      String atr = Mono.just(test).block();
      JsonNode a = new ObjectMapper().readValue(atr, JsonNode.class);
      a.toPrettyString();
      System.out.println(a.toPrettyString());
   }

  public static void main(String[] args) throws JsonProcessingException {
    testPrintAfterUnBlock();
    testPrintInMono();

   }
}

相关问题