使用 Rest 客户端和对象映射器从字符串反序列化 Json

问题描述 投票:0回答:1

我正在使用 Spring Boot 3.2.2 在 Java 17 中制作 REST API。我的 API 调用外部 REST API。所说的 API,尽管它确实返回一个 json,但它并没有以典型的方式执行。它返回的是 json string,而不是 json object

这个:

"{\"Code\":\"123-456\",\"Number\":1}"

不是这个:

{
  "Code": "123-456",
  "Number": 1
}

我有一个课程来获取回复:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ApiResponse {
  @JsonProperty("Code")
  private String code;
  @JsonProperty("Number")
  private String number;
}

现在使用此代码:

ApiResponse response = restClient.post()
    .uri(url)
    .contentType(MediaType.APPLICATION_JSON)
    .body(request.toJsonString())
    .retrieve()
    .body(ApiResponse.class);

这个替代代码:

String responseBody = restClient.post()
    .uri(url)
    .contentType(MediaType.APPLICATION_JSON)
    .body(request.toJsonString())
    .retrieve()
    .body(String.class);

ApiResponse response;

try {
  response = objectMapper.readValue(responseBody, ApiResponse);
} catch(...) {
  ...
}

return response;

在这两种情况下,它都在反序列化部分失败。在第一种情况下,它在

.body(...)
中,在第二种情况下,它在
objectMapper.readValue(...)
中。

抛出的异常是:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.example.test.models.ApiResponse` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"Code":"123-456","Number":1}')

同样,有问题的 json 字符串是:

"{\"Code\":\"123-456\",\"Number\":1}"

我似乎无法将其反序列化到类中。我是不是错过了什么?

java json spring-boot jackson json-deserialization
1个回答
0
投票

您得到的字符串是对符号

"
进行转义的。因此,您看到的不是
"
,而是
\"
,如果您想在字符串中包含符号
"
,则必须在代码中键入该内容。因此,在您的代码中运行代码,将每次出现的
\"
替换为
"
,然后在新字符串上运行代码,这应该可以工作。因此,将您的代码更改为:

try {
  responseBody = responseBody .replace("\\\"", "\"");
  response = objectMapper.readValue(responseBody, ApiResponse);
} catch(...) {
  ...
}

这应该可以解决您的问题。 另外,我编写了一个小实用程序,可以帮助您序列化和反序列化 Json,它是

ObjectMapper
类的薄包装器。它允许您只调用一些静态方法,而无需实例化
ObjectMapper
类。在这种情况下,您可以在代码中替换该行

  response = objectMapper.readValue(responseBody, ApiResponse);

用线:

response = JsonUtils.readObjectFromJsonString(responseBody, ApiResponse);

如果您感兴趣,请参阅JsonUtils 类的 Javadoc。它是我编写和维护的开源 MgntUtils 库的一部分。您可以从 Maven Central 获取该库作为 Maven 工件,或者从 Github

获取 Jar(也提供源代码和 Javadoc)
© www.soinside.com 2019 - 2024. All rights reserved.