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

Android新手求助:解析深层嵌套JSON API数据时遇错误

Fixing Deeply Nested JSON Parsing Issues in Android

Hey there! Let's work through this nested JSON parsing problem you're facing as an Android newbie—deeply structured JSON can feel overwhelming at first, but once you map out the model classes correctly, it gets way easier.

First, let's recap your API response snippet for reference:

{ 
  "report":{ 
    "sr":"28", 
    "type":"Basic", 
    "food":{ 
      "ndbno":"01009", 
      "name":"Cheese, cheddar", 
      "ds":"Standard Reference", 
      "manu":"", 
      "ru":"g", 
      "nutrients":[{ 
        "nutrient_id":"255", 
        "name":"Water", 
        "derivation":"NONE", 
        "group":"Proximates", 
        "unit":"g", 
        "value":"37.02", 
        "measures":[{ 
          "label":"cup, diced", 
          "eqv":"..." 
        }]
      }]
    }
  }
}

Common Causes of Your Parsing Error

  • Mismatched field names between your model classes and JSON keys
  • Incorrect data types (e.g., using int for a JSON string value like "28")
  • Forgetting to account for nested objects/arrays (like nutrients being an array, not a single object)
  • Missing the outermost wrapper (your data starts with report, so you need a top-level class to hold that)

Step-by-Step Solution Using Gson (Android's Go-To Parsing Library)

Gson simplifies JSON parsing by mirroring your JSON structure with Java/Kotlin classes. Let's build those classes step by step.

1. Add Gson Dependency (If You Haven't Already)

In your module-level build.gradle file:

dependencies {
    implementation 'com.google.code.gson:gson:2.10.1'
}

2. Create Model Classes

You need a class for every nested object/array in the JSON:

Top-Level Response Class

Holds the outermost report object:

import com.google.gson.annotations.SerializedName;

public class ReportResponse {
    @SerializedName("report")
    private Report report;

    // Getters and Setters
    public Report getReport() { return report; }
    public void setReport(Report report) { this.report = report; }
}

Report Class

Matches the report object in JSON:

import com.google.gson.annotations.SerializedName;

public class Report {
    @SerializedName("sr")
    private String sr;
    @SerializedName("type")
    private String type;
    @SerializedName("food")
    private Food food;

    // Getters and Setters
    public String getSr() { return sr; }
    public void setSr(String sr) { this.sr = sr; }
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
    public Food getFood() { return food; }
    public void setFood(Food food) { this.food = food; }
}

Food Class

Includes the nutrients array:

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

public class Food {
    @SerializedName("ndbno")
    private String ndbno;
    @SerializedName("name")
    private String name;
    @SerializedName("ds")
    private String ds;
    @SerializedName("manu")
    private String manu;
    @SerializedName("ru")
    private String ru;
    @SerializedName("nutrients")
    private List<Nutrient> nutrients;

    // Getters and Setters
    public String getNdbno() { return ndbno; }
    public void setNdbno(String ndbno) { this.ndbno = ndbno; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public List<Nutrient> getNutrients() { return nutrients; }
    public void setNutrients(List<Nutrient> nutrients) { this.nutrients = nutrients; }
    // Add getters/setters for ds, manu, ru
}

Nutrient Class

Includes the measures array:

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

public class Nutrient {
    @SerializedName("nutrient_id")
    private String nutrientId;
    @SerializedName("name")
    private String name;
    @SerializedName("derivation")
    private String derivation;
    @SerializedName("group")
    private String group;
    @SerializedName("unit")
    private String unit;
    @SerializedName("value")
    private String value;
    @SerializedName("measures")
    private List<Measure> measures;

    // Getters and Setters
    public String getNutrientId() { return nutrientId; }
    public void setNutrientId(String nutrientId) { this.nutrientId = nutrientId; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public List<Measure> getMeasures() { return measures; }
    public void setMeasures(List<Measure> measures) { this.measures = measures; }
    // Add getters/setters for other fields
}

Measure Class

Matches each item in the measures array:

import com.google.gson.annotations.SerializedName;

public class Measure {
    @SerializedName("label")
    private String label;
    @SerializedName("eqv")
    private String eqv; // Use Double if the full JSON returns a number here

    // Getters and Setters
    public String getLabel() { return label; }
    public void setLabel(String label) { this.label = label; }
    public String getEqv() { return eqv; }
    public void setEqv(String eqv) { this.eqv = eqv; }
}

3. Parse the JSON

Once your models are set up, parse the API response string like this:

import com.google.gson.Gson;

// Assume you have the JSON string from your API call
String jsonString = yourApiResponseString;

Gson gson = new Gson();
ReportResponse response = gson.fromJson(jsonString, ReportResponse.class);

// Access data layer by layer
Report report = response.getReport();
Food cheddarCheese = report.getFood();
List<Nutrient> nutrients = cheddarCheese.getNutrients();

// Example: Loop through nutrients and their measures
for (Nutrient nutrient : nutrients) {
    Log.d("JSON_PARSE", "Nutrient: " + nutrient.getName() + " (" + nutrient.getValue() + nutrient.getUnit() + ")");
    for (Measure measure : nutrient.getMeasures()) {
        Log.d("JSON_PARSE", "  Measure: " + measure.getLabel() + " - " + measure.getEqv());
    }
}

Pro Tips to Avoid Future Headaches

  • Always use @SerializedName to map JSON keys to class fields—this fixes mismatches like nutrient_id vs nutrientId.
  • Use List instead of arrays for JSON arrays (Gson handles lists more reliably).
  • Double-check data types: If JSON returns a number as a string (like "37.02"), use String in your model first, then convert to double if needed.
  • If you're using Retrofit, use Call<ReportResponse> as your API interface return type—Retrofit will handle parsing automatically.

I remember struggling with nested JSON when I first started Android development too—small mismatches in model classes are usually the culprit. Take it slow, map each layer one by one, and you'll get it working!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:27:52