发布于2026-07-06 阅读(0)
扫一扫,手机访问
开发中经常遇到这样的场景:JSON响应里某个字段偶尔会缺席,而业务逻辑却需要它提供一个保底值。比如description字段缺失时,直接用title填充——这种事情听着不复杂,但真用GSON去做,发现@SerializedName完全帮不上忙。

@SerializedName的作用其实很单纯:它只负责把JSON里奇奇怪怪的字段名映射到Ja va属性上,比如把"desc"映射成description。可一旦涉及“字段不存在时自动拿另一个字段的值来填”——这就是运行时业务逻辑了,静态注解根本管不了。这时候必须得请出GSON最灵活的扩展机制:自定义反序列化器(JsonDeserializer)。
下面是一个可直接运行的方案,重点围绕Book的定制化解析展开。
public static class BookDeserializer implements JsonDeserializer{ @Override public Book deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { JsonObject obj = json.getAsJsonObject(); // 必须存在的字段:title(假设 JSON 中 title 总是存在) String title = obj.get("title").getAsString(); // 可选字段:description,缺失时 fallback 到 title String description = Optional.ofNullable(obj.get("description")) .map(JsonElement::getAsString) .orElse(title); return new Book(title, description); }}
这里有几个细节值得注意:
- 用Optional安全提取description,避免空指针这种低级问题;
- obj.get("description")返回null表示JSON里根本没有这个字段(不是值为null),所以要判空后再取值;
- 构造Book实例时顺手就把兜底逻辑做完了,领域对象拿到的永远是一份完整的数据。
把自定义解析器绑定到Gson实例上也很直接:
Gson gson = new GsonBuilder() .registerTypeAdapter(Book.class, new BookDeserializer()) .create();// 输入为 BookList 数组格式(注意原始 JSON 是数组)BookList[] bookLists = gson.fromJson(jsonString, BookList[].class);
BookList和Book是abstract class,GSON默认没法实例化抽象类。实际开发中建议改成final class + 私有字段 + getter/setter,或者用@JsonAdapter在字段级别指定解析器。JsonObject的解析逻辑,避免重复getAsJsonObject()。description缺失时要去查数据库——改deserialize()方法就行,业务模型完全不受侵扰。description存在,以及description彻底缺失(不是值为null,而是字段整个不存在)。确保回退行为稳如老狗。@SerializedName是静态映射工具,字段级默认值属于运行时业务逻辑,这事就得交给JsonDeserializer来干。这个方案以最小侵入的方式,在解析阶段就把数据补全了,上层代码拿到的永远是符合契约的对象——这是写健壮JSON API客户端时,值得养成的一个习惯。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8