如何使用Gson将字符串值映射的JSON反序列化为不同类实例
Gson 分别反序列化行情数据与错误信息的方案
场景说明
某券商的API返回JSON结构如下,其中动态键(如MSFT、AAPL)对应行情数据,errors字段单独存放错误信息:
{ "MSFT": { "assetMainType": "EQUITY", "assetSubType": "COE", "quoteType": "NBBO", ... }, "AAPL": { "assetMainType": "EQUITY", "assetSubType": "COE", "quoteType": "NBBO", ... }, "errors": { "invalidSymbols": [ "XYZZ" ] } }
我们需要用Gson将行情数据映射到Map<String, Quote>,同时把errors字段直接映射到独立的错误类,替代原有的组合类方案。
具体实现方案
1. 定义基础实体类
分别定义行情类和错误类,各自只包含对应业务字段:
// 行情数据类 public class Quote { public String assetMainType; public String assetSubType; public String quoteType; // 其他行情相关字段... } // 错误信息类 public class ApiError { public List<String> invalidSymbols; // 其他错误相关字段(如有)... }
2. 定义结果包装类
创建一个类统一存放解析后的行情数据和错误信息:
public class QuoteResult { public final Map<String, Quote> quotes; public final ApiError errors; public QuoteResult(Map<String, Quote> quotes, ApiError errors) { this.quotes = quotes; this.errors = errors; } }
3. 自定义JSON反序列化器
实现JsonDeserializer接口,手动分配JSON字段到对应类:
public class QuoteResultDeserializer implements JsonDeserializer<QuoteResult> { @Override public QuoteResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = json.getAsJsonObject(); Map<String, Quote> quotesMap = new HashMap<>(); ApiError apiError = null; // 遍历所有JSON键值对 for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { String key = entry.getKey(); JsonElement value = entry.getValue(); if ("errors".equals(key)) { // 解析错误字段到ApiError类 apiError = context.deserialize(value, ApiError.class); } else { // 解析行情字段到Quote类并存入Map Quote quote = context.deserialize(value, Quote.class); quotesMap.put(key, quote); } } return new QuoteResult(quotesMap, apiError); } }
4. 注册反序列化器并解析
将自定义解析器注册到Gson实例,完成JSON解析:
// 构建带自定义解析器的Gson实例 Gson gson = new GsonBuilder() .registerTypeAdapter(QuoteResult.class, new QuoteResultDeserializer()) .create(); // 解析JSON字符串 QuoteResult result = gson.fromJson(jsonResponse, QuoteResult.class); // 使用解析结果 Map<String, Quote> stockQuotes = result.quotes; ApiError errorInfo = result.errors; if (errorInfo != null && errorInfo.invalidSymbols != null) { // 处理无效符号逻辑 for (String invalidSymbol : errorInfo.invalidSymbols) { System.out.println("无效符号:" + invalidSymbol); } }
内容的提问来源于stack exchange,提问作者John Churchill
相关产品推荐
相关产品推荐

