어려움은 json 레이블이 Kraken api의 나머지 응답에서 부분적으로 동적이라는 것입니다. 처음에는 작업 사례를 소개합니다. Kraken 거래 API를 연결하여 통화를 자산으로 가져오고 json에서 다음 결과를 얻었습니다.
{
"error": [],
"result": {
"AAVE": {
"aclass": "currency",
"altname": "AAVE",
"decimals": 10,
"display_decimals": 5
},
"ZUSD": {
"aclass": "currency",
"altname": "USD",
"decimals": 4,
"display_decimals": 2
}
}
}
이 예에서 AAVA 및 ZUSD는 동적 레이블입니다. 임베디드 Jackson을 사용하여 OpenFeign 프레임 워크에서 구문 분석합니다. 결과 부분은 다음과 같은 일반 클래스로 처리됩니다.
public class Response<T> {
private List<String> error = new ArrayList<>();
private T result;
// getter and setters
}
자산의 루트 클래스로서 동적 레이블 AAVA 및 ZUSD는 맵에서 처리합니다.
public class AssetInfoResponse extends
Response<Map<String, AssetInfo>> {
}
pojo AssetInfo :
public class AssetInfo implements Serializable{
@JsonProperty("altname")
private String alternateName;
@JsonProperty("aclass")
private String assetClass;
@JsonProperty("decimals")
private Byte decimals;
@JsonProperty("display_decimals")
private Byte displayDecimals;
// getters, setters ...
}
위의 경우는 완벽하게 작동하며 동적 레이블이있는 솔루션도 마찬가지입니다.
다음은 ohlc 데이터에 대한 응답입니다. 비슷해 보이며 다음 경우에 deserialization 문제를 해결할 아이디어가 없습니다.
{
"error": [],
"result": {
"XXBTZEUR": [
[
1613212500,
"39000.1",
"39010.1",
"38972.3",
"38994.1",
"38998.1",
"3.23811638",
70
],
[
1613212560,
"38994.3",
"39014.5",
"38994.3",
"39014.5",
"38997.3",
"0.95105956",
11
]
],
"last": 1613212500
}
}
문제의 원인은 "last": 1613212500
대지 경계선입니다. 이 줄을 제거하면 응답이 문제없이 구문 분석 될 수 있습니다. 나는 다음 클래스로 그것을 해결하려고 노력하고 Response
있습니다.
public class OhlcLastResponse<T> extends Response<T> {
private Long last;
// getters and setters
}
다음 클래스는 prevourious 클래스를 확장하며 objectmapper의 루트 클래스입니다.
public class OhlcResponse
extends OhlcLastResponse<Map<String, List<Candelstick>>> {
}
그리고 캔들 스틱 데이터를 보유하는 포조 :
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
@JsonPropertyOrder({ "time", "open", "high", "low",
"close", "vwap", "volume", "count" })
public class Candelstick implements Serializable {
private Integer time;
private BigDecimal open;
private BigDecimal high;
private BigDecimal low;
private BigDecimal close;
private BigDecimal vwap;
private BigDecimal volume;
private Integer count;
// getters and setters ...
}
그리고 여기에 오류가 있습니다.
"38997.3",
"0.95105956",
11
]
],
"last": 1613212500
}
}
"; line: 26, column: 11] (through reference chain: OhlcResponse["result"]->java.util.LinkedHashMap["last"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
Jackson은이 last
부동산을지도 에 넣으려고 하지만지도는 ],
. 26 행 last
은 json 파일 의 레이블 이있는 행입니다 .
이 json을 구문 분석 할 가능성이 있습니까? 배열이 대괄호로 닫혀 있기 때문에 가능해야한다고 생각합니다.
나머지 클라이언트를 github 에서 호스팅했습니다 . 오류를 재현하려면 복제하고 mvn test
.
이 경우 형식 처리가 매우 어렵 기 때문에 솔루션은 deserializer입니다. deserializer는 배열 또는 단일 마지막 값의 두 경우 중에서 결정하고 배열의 경우 CandleStick
Class에 대한 deserializer를 호출합니다 .
public class OhlcDeserializer extends JsonDeserializer<OhclPayload> {
@Override
public OhclPayload deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
List<CandleStick> candleSticks = new ArrayList<CandleStick>();
Long last = null;
ObjectCodec objectCodec = p.getCodec();
JsonNode jsonNode = objectCodec.readTree(p);
Iterator<Entry<String, JsonNode>> payloadIterator = jsonNode.fields();
while (payloadIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = payloadIterator.next();
if (entry.getKey().equals("last")) {
last = entry.getValue().asLong();
} else if (entry.getValue().isArray()) {
for (JsonNode node : entry.getValue()) {
CandleStick cs = p.getCodec().treeToValue(node, CandleStick.class);
candleSticks.add(cs);
}
}
}
return new OhclPayload(candleSticks, last);
}
}
OhclResponse를 다음과 같이 변경했습니다.
public class OhlcResponse extends Response<OhclPayload> {
}
그리고 deserializer에 대한 OhlcPayload 클래스를 삽입합니다.
@JsonDeserialize(using = OhlcDeserializer.class)
public class OhclPayload {
private List<CandleStick> candleSticks;
private Long last;
// getters and setters
}
그게 다야.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다