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

使用Gson解析嵌套JSON返回空值问题求助

排查FDA API JSON解析空值问题

Hey Kyle, 碰到FDA API解析JSON返回空值的问题确实挺头疼的,我帮你梳理几个最可能的原因和解决办法,结合你提到的Gson工具来分析:

1. 没匹配到FDA API的嵌套层级

FDA API的响应是多层嵌套的,根结构里的results数组才是实际的药物标签数据,如果你直接把实体类映射到根对象,而没从results里取数据,肯定会拿到空值。

比如浏览器访问目标URL的响应结构大概是这样:

{
  "meta": { ... },
  "results": [
    {
      "brand_name": ["XXX"],
      "openfda": { ... },
      ...
    }
  ]
}

你必须先解析整个根响应,再从results数组里提取单个标签对象。

2. 字段名映射不匹配

FDA API的字段是下划线命名(比如brand_name、manufacturer_name),而Java习惯用驼峰命名。如果你的实体类字段没加@SerializedName注解,Gson会默认按字段名严格匹配,导致映射失败返回空。

3. 嵌套对象的实体类定义缺失

像openfda这种嵌套对象,你必须为它单独定义对应的实体类,否则Gson无法解析这部分数据,会返回null。

具体解决示例

第一步:定义正确的实体类

// 根响应类,对应API返回的最外层结构
public class FdaDrugResponse {
    private Meta meta;
    private List<DrugLabel> results;

    // Getter和Setter方法
    public Meta getMeta() { return meta; }
    public void setMeta(Meta meta) { this.meta = meta; }
    public List<DrugLabel> getResults() { return results; }
    public void setResults(List<DrugLabel> results) { this.results = results; }
}

// 可选:如果需要meta里的信息,就定义这个类,不需要可以忽略
public class Meta {
    private String disclaimer;
    // 其他meta字段按需添加
}

// 药物标签实体类,对应results里的单个对象
public class DrugLabel {
    // 用@SerializedName匹配API的下划线字段
    @SerializedName("brand_name")
    private List<String> brandName;
    
    @SerializedName("openfda")
    private OpenFda openFda;

    // Getter和Setter方法
    public List<String> getBrandName() { return brandName; }
    public void setBrandName(List<String> brandName) { this.brandName = brandName; }
    public OpenFda getOpenFda() { return openFda; }
    public void setOpenFda(OpenFda openFda) { this.openFda = openFda; }
}

// OpenFDA嵌套对象的实体类
public class OpenFda {
    @SerializedName("manufacturer_name")
    private List<String> manufacturerName;

    // Getter和Setter方法
    public List<String> getManufacturerName() { return manufacturerName; }
    public void setManufacturerName(List<String> manufacturerName) { this.manufacturerName = manufacturerName; }
}

第二步:修改解析代码

确保先解析根响应,再从results数组中提取数据:

package com.example.user.searchbarapp;

import java.net.URL;
import java.net.HttpURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import com.google.gson.Gson;
import java.util.List;

public class FdaApiParser {
    public static void main(String[] args) {
        try {
            // 建议加limit参数确保返回结果,默认API会返回少量结果
            URL url = new URL("https://api.fda.gov/drug/label.json?limit=1");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            conn.disconnect();

            // 解析根响应
            Gson gson = new Gson();
            FdaDrugResponse fdaResponse = gson.fromJson(response.toString(), FdaDrugResponse.class);

            // 检查results数组是否有数据
            if (fdaResponse.getResults() != null && !fdaResponse.getResults().isEmpty()) {
                DrugLabel firstLabel = fdaResponse.getResults().get(0);
                System.out.println("品牌名:" + firstLabel.getBrandName());
                System.out.println("生产商:" + firstLabel.getOpenFda().getManufacturerName());
            } else {
                System.out.println("FDA API未返回任何结果");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

额外排查点

  • 检查请求URL是否正确:如果要查询特定药物,需要加search参数,比如https://api.fda.gov/drug/label.json?search=brand_name:"Tylenol"
  • 打印完整的JSON响应,确认返回的字段名和你要解析的是否一致
  • 确认Gson依赖已正确引入(比如Maven的com.google.code.gson:gson:2.10.1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:20:39