使用Spring WebClient反序列化具有动态模式的响应体。

huangapple go评论67阅读模式
英文:

Deserialize response body with dynamic schema using Spring WebClient

问题

我正在使用Spring WebClient来向外部API发送请求。但是有一个端点在成功的HTTP请求时不返回统一的JSON。当它有数据返回时,我会得到以下JSON响应:

{
    "String A": "d7e75c1d-71d1-4628-ad01-cd65a7aabd52",
    "String B": "4a28c303-fb5c-4648-926e-fd2db1178838"
}

然而,当没有数据时,它会返回一个空的JSON数组:

[]

在这两种情况下,HTTP请求都以200响应代码完成。

以下是执行请求的代码:

public Map<String, UUID> getIdsByDisplayNames(List<String> displayNames) {
    return webClient.get()
            .uri(uriBuilder -> {
                uriBuilder.path("/api/display-names/account-ids");
                for (String displayName : displayNames) {
                    uriBuilder.queryParam("displayName[]", displayName);
                }
                return uriBuilder.build();
            })
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<Map<String, UUID>>() {})
            .block();
}

当响应体中有一个JSON对象时,它运行良好,但当端点返回一个空数组时,我会得到一个异常:

org.springframework.core.codec.DecodingException: JSON decoding error: Cannot deserialize value of type java.util.LinkedHashMap<java.lang.String,java.util.UUID> from Array value (token JsonToken.START_ARRAY)

我该如何在我的代码中解决这个问题?

英文:

I'm using Spring WebClient to make requests to external API. But there's an endpoint that does not return a uniform json on successful HTTP request. When it has data to return I get a response with following json:

{
    &quot;String A&quot;: &quot;d7e75c1d-71d1-4628-ad01-cd65a7aabd52&quot;,
    &quot;String B&quot;: &quot;4a28c303-fb5c-4648-926e-fd2db1178838&quot;
}

Howewer when there's nothing it returns an empty json array:

[]

In both cases HTTP request completes with 200 response code.

Here's my code that does a request:

public Map&lt;String, UUID&gt; getIdsByDisplayNames(List&lt;String&gt; displayNames) {
        return webClient.get()
                .uri(uriBuilder -&gt; {
                    uriBuilder.path(&quot;/api/display-names/account-ids&quot;);
                    for (String displayName : displayNames) {
                        uriBuilder.queryParam(&quot;displayName[]&quot;, displayName);
                    }
                    return uriBuilder.build();
                })
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference&lt;Map&lt;String, UUID&gt;&gt;() {})
                .block();
    }

It works well when there's a json object in response body but when endpoint returns an empty array I get an exception:

> org.springframework.core.codec.DecodingException: JSON decoding error: Cannot deserialize value of type java.util.LinkedHashMap&lt;java.lang.String,java.util.UUID&gt; from Array value (token JsonToken.START_ARRAY)

How can I solve it in my code?

答案1

得分: 0

代替请求Map&lt;String, UUID&gt;,您可以请求JsonNode

该类提供了一些方法isArrayisObject,用于确定响应是JSON对象还是JSON数组。

英文:

Instead of asking for a Map&lt;String, UUID&gt;, you could ask for a JsonNode.

This class provides some methods isArray and isObject to determine if the response is a JSON Object or a JSON Array.

huangapple
  • 本文由 发表于 2023年7月10日 14:07:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76651036.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定