更新时间:2022-10-17 21:44:21
要匹配AccountOrderList
类的响应,json必须是这样的
{帐户订单":[{"符号": "XRPETH",订单编号":12122,"clientOrderId": "xxx","价格": "0.00000000","origQty": "25.00000000","executedQty": "25.00000000","状态": "已满","timeInForce": "GTC","type": "市场","side": "买入","stopPrice": "0.00000000","icebergQty": "0.00000000",时间":1514558190255,正在工作":真},{"符号": "XRPETH",订单号":1212,"clientOrderId": "xxx","价格": "0.00280000","origQty": "24.00000000","executedQty": "24.00000000","状态": "已满","timeInForce": "GTC",类型":限制","side": "卖","stopPrice": "0.00000000","icebergQty": "0.00000000",时间":1514640491287,正在工作":真},....]}
这是错误消息所说的超出 START_ARRAY 令牌"
如果你不能改变响应,那么改变你的代码来接受这样的数组
this.webClient.get().uri(payload).accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(AccountOrder[].class).log();
你可以把这个数组转成List然后返回.
I have a problem during the deserialization of a json array using Spring. I have this json response from a service:
[
{
"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
},
....
]
I get this json using the new WebClient from Spring WebFlux, here the code:
@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 is a simple pojo that maps the fields.
Actually, when I hit a get it says:
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]
How can I deserialize the json properly using the new webflux module? What am I doing wrong?
UPDATE 05/02/2018
Both answers are correct. They addressed perfectly my question but at the end I decided to use a slightly different approach:
@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();
});
}
An alternative to this could be to return directly A Flux so you don't have to convert it to a list. (that's what flux are: a collection of n elements).
For the response to be matched with AccountOrderList
class, json has to be like this
{
"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
},
....
]
}
This is what the error message says "out of START_ARRAY token"
If you cannot change the response, then change your code to accept Array like this
this.webClient.get().uri(payload).accept(MediaType.APPLICATION_JSON)
.retrieve().bodyToMono(AccountOrder[].class).log();
You can convert this array to List and then return.