我在使用Spring反序列化json数组期间遇到问题。我从服务获得此json响应:
[ { "symbol": "XRPETH", "orderId": 12122, "clientOrderId": "xxx", "price": "0.00000000", "origQty": "25.00000000", "executedQty": "25.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "MARKET", "side": "BUY", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "time": 1514558190255, "isWorking": true }, { "symbol": "XRPETH", "orderId": 1212, "clientOrderId": "xxx", "price": "0.00280000", "origQty": "24.00000000", "executedQty": "24.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "time": 1514640491287, "isWorking": true }, .... ]
我使用Spring WebFlux的新WebClient获取此json,代码如下:
@Override public Mono<AccountOrderList> getAccountOrders(String symbol) { return binanceServerTimeApi.getServerTime().flatMap(serverTime -> { String apiEndpoint = "/api/v3/allOrders?"; String queryParams = "symbol=" +symbol.toUpperCase() + "×tamp=" + serverTime.getServerTime(); String signature = HmacSHA256Signer.sign(queryParams, secret); String payload = apiEndpoint + queryParams + "&signature="+signature; log.info("final endpoint:"+ payload); return this.webClient .get() .uri(payload) .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(AccountOrderList.class) .log(); }); }
AccountOrderList
public class AccountOrderList { private List<AccountOrder> accountOrders; public AccountOrderList() { } public AccountOrderList(List<AccountOrder> accountOrders) { this.accountOrders = accountOrders; } public List<AccountOrder> getAccountOrders() { return accountOrders; } public void setAccountOrders(List<AccountOrder> accountOrders) { this.accountOrders = accountOrders; } }
AccountOrder是映射字段的简单pojo。
实际上,当我点击“ get”时,它会说:
org.springframework.core.codec.DecodingException: JSON decoding error: Cannot deserialize instance of `io.justin.demoreactive.domain.AccountOrder` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `io.justin.demoreactive.domain.AccountOrder` out of START_ARRAY token at [Source: UNKNOWN; line: -1, column: -1]
如何使用新的webflux模块正确反序列化json?我究竟做错了什么?
更新05/02/2018
两个答案都是正确的。他们完美地解决了我的问题,但最后我决定使用稍微不同的方法:
@Override public Mono<List<AccountOrder>> getAccountOrders(String symbol) { return binanceServerTimeApi.getServerTime().flatMap(serverTime -> { String apiEndpoint = "/api/v3/allOrders?"; String queryParams = "symbol=" +symbol.toUpperCase() + "×tamp=" + serverTime.getServerTime(); String signature = HmacSHA256Signer.sign(queryParams, secret); String payload = apiEndpoint + queryParams + "&signature="+signature; log.info("final endpoint:"+ payload); return this.webClient .get() .uri(payload) .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToFlux(AccountOrder.class) .collectList() .log(); }); }
替代方法是直接返回A Flux,因此您不必将其转换为列表。(这就是通量:n个元素的集合)。
为了使响应与AccountOrderList类匹配,json必须像这样
{ "accountOrders": [ { "symbol": "XRPETH", "orderId": 12122, "clientOrderId": "xxx", "price": "0.00000000", "origQty": "25.00000000", "executedQty": "25.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "MARKET", "side": "BUY", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "time": 1514558190255, "isWorking": true }, { "symbol": "XRPETH", "orderId": 1212, "clientOrderId": "xxx", "price": "0.00280000", "origQty": "24.00000000", "executedQty": "24.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "time": 1514640491287, "isWorking": true }, .... ] }
这就是错误消息说“ START_ARRAY令牌不足 ”的意思
如果您无法更改响应,请更改代码以接受Array,如下所示
this.webClient.get().uri(payload).accept(MediaType.APPLICATION_JSON) .retrieve().bodyToMono(AccountOrder[].class).log();
您可以将此数组转换为List,然后返回。