在 Java Spring Boot 中使用 Rest Client 反序列化文本 json

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

我在处理来自 Spring 的外部 REST API 和 REST 客户端的响应时遇到问题。我目前正在使用新的(+3.2.0,如果我没记错的话)“Rest Client”,但我也会接受解决“Web Client”问题的答案,如果它适用并且您找不到新 Rest 客户端的答案。

简单地说,我向返回正文的外部 REST API 发出请求。内容类型标头内容为:

application/json; charset=utf-8

正文本身实际上并不是 Web 客户端或 Rest 客户端(我想)能够毫无问题地反序列化的普通 json。它似乎是一个文本 json,尽管该媒体类型本身并不存在。响应正文示例:

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

让我重申,这是字面回应,而不是这个:

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

我尝试过这个但没有成功:

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

我也尝试过:

{
  Object response = restClient.post()
    .uri(url)
    .contentType(MediaType.APPLICATION_JSON)
    .body(request)
    .retrieve()
    .body(String.class);
}

这两个都会抛出相同的错误,它们在

.body(...) part
处中断。我也尝试过
.toEntity(...)
,它也在那里破裂。我只展示第一个:

Error while extracting response for type [com.example.test.models.ApiResponse] and content type [application/json;charset=utf-8]

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
at [Source: (jdk.internal.net.http.ResponseSubscribers$HttpResponseInputStream); line: 1, column: 1]

我的猜测是,因为响应的内容类型标头是

application/json
,所以它需要一个以
{
开头的 json。然而,响应以
"
开头,因为就像我说的,它不是一个普通的 json,它是字符串文字格式的 json。因此
Cannot deserialize value of type 'java.lang.String' from Object value (token 'JsonToken.START_OBJECT')

我设法将其更改为“Rest Template”并执行其他操作,但我不想这样做。我想通过 Rest 客户端/Web 客户端来实现此功能。

请帮忙,我不知道还能做什么。另外,有人故意这样做有什么理由吗?我的意思是,使响应成为 json 字符串而不是普通的 json。如果这个外部 REST API 以正常的 json 响应(我猜),我现在就不会写这个。

编辑:我使用默认的 Rest 客户端和默认的消息转换器。

java json spring rest client
1个回答
0
投票

我还没能尝试解决方案,但它可能会给你一些想法:

您尝试过使用

bodyToMono(String.class)
来代替吗?即使一般不推荐,您也可以通过
.block()
关注它。

然后使用 jackson 将你的responseString转换为json:

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

// ...

String responseString = restClient.post()
    .uri(url)
    .contentType(MediaType.APPLICATION_JSON)
    .body(request)
    .retrieve()
    .bodyToMono(String.class)
    .block();

ObjectMapper objectMapper = new ObjectMapper();
JsonNode responseJson = objectMapper.readTree(responseString);
© www.soinside.com 2019 - 2024. All rights reserved.