使用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
相关产品推荐
相关产品推荐

