You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

反序列化Long类型值失败,如何正确获取Candlestick的openTime?

问题描述

我在Android的Activity中调用Coins类的函数,尝试将以下代码转为Kotlin运行:

fun timeRequest() {
    GlobalScope.launch(Dispatchers.IO) {
        val tickerStatistics = client.get24HrPriceStatistics("NEOETH")
        withContext(Dispatchers.Main) {
            println(tickerStatistics.lastPrice)
        }
    }
}

但出现如下反序列化错误:

Cannot deserialize value of type `java.lang.Long` from String "0.09700000": not a valid Long value

我猜测是类型转换问题,即使把:

override fun doInBackground(vararg params: Void?): Long

修改为:

override fun doInBackground(vararg params: Void?): Float

也没有任何效果。

错误指向以下代码行(变量theLastTime为Long类型):

var theLastTime = client.getCandlestickBars("NEOETH", CandlestickInterval.WEEKLY)[0].openTime

API返回的Candlestick示例如下:

[Candlestick[openTime=1506297600000,open=0.09700000,high=0.12000100,low=0.05500000,close=0.11986900,volume=25709.37000000,closeTime=1506902399999,quoteAssetVolume=2649.80091051,numberOfTrades=2435,takerBuyBaseAssetVolume=10520.59000000,takerBuyQuoteAssetVolume=1101.94985388], ...] 

使用的Candlestick Java类代码如下:

package com.binance.api.client.domain.market;

import com.binance.api.client.constant.BinanceApiConstants;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import org.apache.commons.lang3.builder.ToStringBuilder;

@JsonFormat(
    shape = Shape.ARRAY
)
@JsonPropertyOrder
@JsonIgnoreProperties(
    ignoreUnknown = true
)
public class Candlestick {
    private Long openTime;
    private String open;
    private String high;
    private String low;
    private String close;
    private String volume;
    private Long closeTime;
    private String quoteAssetVolume;
    private Long numberOfTrades;
    private String takerBuyBaseAssetVolume;
    private String takerBuyQuoteAssetVolume;

    public Candlestick() {
    }

    public Long getOpenTime() {
        return this.openTime;
    }

    public void setOpenTime(Long openTime) {
        this.openTime = openTime;
    }

    public String getOpen() {
        return this.open;
    }

    public void setOpen(String open) {
        this.open = open;
    }

    public String getHigh() {
        return this.high;
    }

    public void setHigh(String high) {
        this.high = high;
    }

    public String getLow() {
        return this.low;
    }

    public void setLow(String low) {
        this.low = low;
    }

    public String getClose() {
        return this.close;
    }

    public void setClose(String close) {
        this.close = close;
    }

    public String getVolume() {
        return this.volume;
    }

    public void setVolume(String volume) {
        this.volume = volume;
    }

    public Long getCloseTime() {
        return this.closeTime;
    }

    public void setCloseTime(Long closeTime) {
        this.closeTime = closeTime;
    }

    public String getQuoteAssetVolume() {
        return this.quoteAssetVolume;
    }

    public void setQuoteAssetVolume(String quoteAssetVolume) {
        this.quoteAssetVolume = quoteAssetVolume;
    }

    public Long getNumberOfTrades() {
        return this.numberOfTrades;
    }

    public void setNumberOfTrades(Long numberOfTrades) {
        this.numberOfTrades = numberOfTrades;
    }

    public String getTakerBuyBaseAssetVolume() {
        return this.takerBuyBaseAssetVolume;
    }

    public void setTakerBuyBaseAssetVolume(String takerBuyBaseAssetVolume) {
        this.takerBuyBaseAssetVolume = takerBuyBaseAssetVolume;
    }

    public String getTakerBuyQuoteAssetVolume() {
        return this.takerBuyQuoteAssetVolume;
    }

    public void setTakerBuyQuoteAssetVolume(String takerBuyQuoteAssetVolume) {
        this.takerBuyQuoteAssetVolume = takerBuyQuoteAssetVolume;
    }

    public String toString() {
        return (new ToStringBuilder(this, BinanceApiConstants.TO_STRING_BUILDER_STYLE)).append("openTime", this.openTime).append("open", this.open).append("high", this.high).append("low", this.low).append("close", this.close).append("volume", this.volume).append("closeTime", this.closeTime).append("quoteAssetVolume", this.quoteAssetVolume).append("numberOfTrades", this.numberOfTrades).append("takerBuyBaseAssetVolume", this.takerBuyBaseAssetVolume).append("takerBuyQuoteAssetVolume", this.takerBuyQuoteAssetVolume).toString();
    }
}

请问如何无错误地获取openTime值?


解决方案

错误原因

问题出在Candlestick类的反序列化字段顺序不匹配:
该类使用@JsonFormat(shape = Shape.ARRAY)指定以数组格式解析API返回数据,但@JsonPropertyOrder注解未明确指定字段顺序,Jackson会默认按字段的字母顺序映射数组元素,导致原本应该映射到字符串类型字段的数值字符串(比如示例中的"0.09700000")被错误地分配给了Long类型字段,从而抛出反序列化异常。

修改doInBackground的返回类型无效,因为错误根源不在AsyncTask的返回值,而是API数据的解析阶段。

解决步骤

修改Candlestick类的@JsonPropertyOrder注解,明确指定与API返回的K线数组完全一致的字段顺序:

@JsonPropertyOrder({
    "openTime",
    "open",
    "high",
    "low",
    "close",
    "volume",
    "closeTime",
    "quoteAssetVolume",
    "numberOfTrades",
    "takerBuyBaseAssetVolume",
    "takerBuyQuoteAssetVolume"
})

这样Jackson就能正确将数组中的每个元素映射到对应的字段,openTime会被正确解析为Long类型,不会再出现类型不匹配的错误。


内容的提问来源于stack exchange,提问作者Ömer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 03:39:53