java - WebClient 无法正确解析 JSON 响应
问题描述
我希望有人可以帮助我几天我一直在努力解决这个问题。
我想用 WebClient 创建一个 Rest Client 来从 API 检索响应。所以我创建了我的 Spring 项目,添加了 webflux、lombok 和 h2。我还创建了一个 DTO 类“CashAccount”和以下方法:
public String retrieveAccountById(String accountId) {
return webClient.get()
.uri(GET_ACCOUNT_BY_ID_V4, accountId)
.header("Auth-Schema", AUTH_SCHEMA)
.header("apikey", API_KEY)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatus::is4xxClientError, response -> {
System.out.println("4xx error");
return Mono.error(new RuntimeException("4xx"));
})
.onStatus(HttpStatus::is5xxServerError, response -> {
System.out.println("5xx error");
return Mono.error(new RuntimeException("5xx"));
})
.bodyToMono(String.class) // .bodyToMono(CashAccount.class)
.block();
}
当我使用“.bodyToMono(String.class)”时,一切正常,我收到了结果:
2:50:27.548 [reactor-http-nio-2] DEBUG org.springframework.core.codec.StringDecoder - [43ed0ff3] [6449a63b-1, L:/192.168.1.72:60756 - R:sandbox.io/210.278.152.97:443] Decoded "{
"status": "OK",
"error": [],
"payload": {"accountId":"80377145","iban":"IT10L01234567890 (truncated)...
相反,当我使用“.bodyToMono(CashAccount.class)”时,我收到一个所有变量都为空的对象:
23:17:31.236 [reactor-http-nio-2] DEBUG org.springframework.http.codec.json.Jackson2JsonDecoder - [43ed0ff3] [77c463f4-1, L:/192.168.1.72:62306 - R:sandbox.io/210.278.152.97:443] Decoded [CashAccount(accountId=null, iban=null, abiCode=null, cabCode=null, countryCode=null, internationalCi (truncated)...]
这是我的 DTO 课程:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CashAccount {
private String accountId;
private String iban;
...
}
我究竟做错了什么?
解决方案
问题是您试图仅将有效负载对象映射到 CashAccount。您的 dto 中还应该有一个状态和错误数组。
关于您的 json 响应:
添加缺少字段的 dto
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseDto {
private String status;
private List<String> error;
private CashAccount payload;
}
然后改变 .bodyToMono(ResponseDto.class)
我建议您使用 @JsonTest 测试您的映射
@JsonTest
class TestMarshalling {
@Autowired ObjectMapper mapper;
@Test
@SneakyThrows
void testmarshalling() {
String response =
"{\n"
+ " \"status\": \"OK\",\n"
+ " \"error\": [],\n"
+ " \"payload\":
{\"accountId\":\"80377145\",\"iban\":\"IT10L01234567890\"}}";
var cashAccount = mapper.readValue(response , ResponseDto.class);
Assertions.assertNotNull(cashAccount.getPayload());
Assertions.assertNotNull(cashAccount.getPayload().getAccountId());
Assertions.assertNotNull(cashAccount.getPayload().getIban());
}
}
推荐阅读
- python - Jinja2 解析 JSON 对象,无法从中获取值
- android - 在使用它们声明依赖项时,Kapt 和 Gradle 中的实现有什么区别?
- entity-framework-core - EF Core 级联删除可为空的外键
- android - 宽度受限的Textview有时在recyclerview中不起作用
- reactjs - 我应该在哪个 AWS 服务中部署我的 react 应用程序
- angular - 如何使用 ngClass 将多个类应用于 div?
- java - Spring Container 和 BeanFactory 的实现之间的关系?
- nsis - NSIS 问题:当“.onInstSuccess”功能未完成时,我可以禁用“MUI_PAGE_FINISH”页面中的“完成”按钮吗?
- django - Django 通道 2 和信号:Websocket 连接失败
- html - “UI 元素状态伪类 (:checked)”属性仍然存在,尽管在移动环境中复选框已取消选中