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

Retrofit解析报错:Expected BEGIN_ARRAY but was BEGIN_OBJECT求助

Fixing Retrofit Parsing Error: Expected BEGIN_ARRAY but was BEGIN_OBJECT

Hey there, let's break down this Retrofit parsing issue you're facing. That error message Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ tells us exactly what's going wrong—your code is expecting the entire JSON response to be an array, but the API is actually returning an object that contains two array fields inside it.

Looking at your response data:

{
"market_cap_by_available_supply": [ [ 1367174841000, 1500517590 ], [ 1367261101000, 1575032004 ] ],
"price_btc": [ [ 1367174841000, 1 ], [ ... ] ]
}

This is a top-level JSON object with two keys, each mapping to a 2D array of numbers. So your data model needs to match this structure, not just a raw array.

Step 1: Create the Correct Data Model

You need a class that represents the top-level object, with fields matching the API's keys. Here are examples for both Java and Kotlin:

Java Model

import com.google.gson.annotations.SerializedName;
import java.util.List;

public class MarketDataResponse {
    @SerializedName("market_cap_by_available_supply")
    private List<long[]> marketCapByAvailableSupply;

    @SerializedName("price_btc")
    private List<long[]> priceBtc;

    // Getters and setters for accessing the data
    public List<long[]> getMarketCapByAvailableSupply() {
        return marketCapByAvailableSupply;
    }

    public void setMarketCapByAvailableSupply(List<long[]> marketCapByAvailableSupply) {
        this.marketCapByAvailableSupply = marketCapByAvailableSupply;
    }

    public List<long[]> getPriceBtc() {
        return priceBtc;
    }

    public void setPriceBtc(List<long[]> priceBtc) {
        this.priceBtc = priceBtc;
    }
}

Kotlin Model (More Concise)

import com.google.gson.annotations.SerializedName

data class MarketDataResponse(
    @SerializedName("market_cap_by_available_supply")
    val marketCapByAvailableSupply: List<LongArray>,
    @SerializedName("price_btc")
    val priceBtc: List<LongArray>
)

Step 2: Update Your Retrofit Interface

Change your API interface to return the new top-level model instead of a list. Here's how:

Java Interface

import retrofit2.Call;
import retrofit2.http.GET;

public interface MarketApi {
    @GET("your-api-endpoint-path") // Replace with your actual endpoint
    Call<MarketDataResponse> fetchMarketData();
}

Kotlin Interface (Using Coroutines)

import retrofit2.Response
import retrofit2.http.GET

interface MarketApi {
    @GET("your-api-endpoint-path") // Replace with your actual endpoint
    suspend fun fetchMarketData(): Response<MarketDataResponse>
}

Step 3: Parse the Response Correctly

Now when you make the API call, use the new model to handle the response:

Java Example

MarketApi marketApi = retrofit.create(MarketApi.class);
marketApi.fetchMarketData().enqueue(new Callback<MarketDataResponse>() {
    @Override
    public void onResponse(Call<MarketDataResponse> call, Response<MarketDataResponse> response) {
        if (response.isSuccessful() && response.body() != null) {
            MarketDataResponse marketData = response.body();
            
            // Access the market cap data
            List<long[]> marketCapEntries = marketData.getMarketCapByAvailableSupply();
            for (long[] entry : marketCapEntries) {
                long timestamp = entry[0]; // 1367174841000
                long marketCapValue = entry[1]; // 1500517590
                // Process each entry as needed
            }
            
            // Access the BTC price data similarly
            List<long[]> priceBtcEntries = marketData.getPriceBtc();
            // ...
        }
    }

    @Override
    public void onFailure(Call<MarketDataResponse> call, Throwable t) {
        // Handle failure cases
        t.printStackTrace();
    }
});

Kotlin Coroutine Example

viewModelScope.launch {
    try {
        val response = marketApi.fetchMarketData()
        if (response.isSuccessful) {
            val marketData = response.body() ?: return@launch
            
            // Process market cap data
            marketData.marketCapByAvailableSupply.forEach { entry ->
                val timestamp = entry[0]
                val marketCapValue = entry[1]
                // Do something with the data
            }
            
            // Process BTC price data
            marketData.priceBtc.forEach { entry ->
                // ...
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

Key Takeaway

The root issue was a mismatch between your expected JSON structure (array) and the actual response (object containing arrays). By updating your data model to reflect the top-level object and adjusting your Retrofit interface to use this model, you'll resolve the parsing error.

内容的提问来源于stack exchange,提问作者Hasu Sarkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:02:03