Jackson 및 WebClient를 사용하여 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();
});
}
Account Order List(계정 주문 목록)
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;
}
}
Account Order는 필드를 매핑하는 단순한 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을 올바르게 시리얼 해제하려면 어떻게 해야 합니까?내가 뭘 잘못하고 있지?
업데이트 2018년 5월 02일
둘 다 정답입니다.그들은 내 질문을 완벽하게 해결했지만, 결국 나는 약간 다른 접근법을 사용하기로 결정했다.
@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개의 원소의 집합입니다).
질문에 대한 업데이트된 답변에 대해bodyToFlux
불필요하게 비효율적이고 의미론적으로도 의미가 없습니다.주문 스트림을 원하지 않기 때문입니다.필요한 것은 단순히 응답을 목록으로 해석할 수 있는 것입니다.
bodyToMono(List<AccountOrder>.class)
는 타입 삭제로 동작하지 않습니다.실행 시 유형을 유지할 수 있어야 하며 스프링은ParameterizedTypeReference
그 경우:
bodyToMono(new ParameterizedTypeReference<List<AccountOrder>>() {})
응답을 일치시키려면AccountOrderList
class, 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
},
....
]
}
오류 메시지에 "out of START_ARRAY 토큰"이라고 표시됩니다.
응답을 변경할 수 없는 경우 다음과 같이 어레이를 받아들이도록 코드를 변경합니다.
this.webClient.get().uri(payload).accept(MediaType.APPLICATION_JSON)
.retrieve().bodyToMono(AccountOrder[].class).log();
이 배열을 목록으로 변환한 후 반환할 수 있습니다.
답변은 간단합니다.List<AccountOrder>
하지만 당신의 POJO는List<AccountOrder>
그럼, 당신의 POJO에 따르면JSON
그래야 한다
{
"accountOrders": [
{
하지만, 당신의JSON
이
[
{
"symbol": "XRPETH",
"orderId": 12122,
....
따라서 불일치와 역직렬화가 실패합니다.로 변경해야 합니다.
bodyToMono(AccountOrder[].class)
언급URL : https://stackoverflow.com/questions/48598233/deserialize-a-json-array-to-objects-using-jackson-and-webclient
'programing' 카테고리의 다른 글
셸 스크립트의 JSON 어레이를 통한 반복 (0) | 2023.03.15 |
---|---|
sysdate에서 년을 빼는 방법 (0) | 2023.03.15 |
AngularJS에서 ngInclude 지시문에 모델을 지정하는 방법은 무엇입니까? (0) | 2023.03.10 |
oracle sql에 해당하는 "show create table" (0) | 2023.03.10 |
$resource 액션을 사용하여 커스텀헤더를 설정하는 방법 (0) | 2023.03.10 |