SerializedName与自定义GSON反序列化器处理嵌套POJO问题
问题描述
我有一段JSON字符串需要解析为Java对象:
"[{\"name\": \"favorite list\", \"books\": [ {\"title\": \"bookTitle1\", \"description\": \"book description\"}, {\"title\": \"bookTitle2\"} ]}]"
对应的Java抽象类定义如下:
public abstract class BookList { public abstract String name; public abstract List<Book> books; } public abstract class Book { public abstract String title; public abstract String description; }
反序列化需求:每个Book对象必须同时包含title和description字段;若JSON中缺失description,则将title的值赋值给description。期望的反序列化结果如下:
[{name: "favorite list", books:[ {"title": "bookTitle1", "description": "book description"}, {"title": "bookTitle2", "description": "bookTitle2"} ]}]
我尝试用@SerializedName注解实现缺失description时用title填充,但未成功。想请教:是否必须为BookList创建自定义反序列化器?处理嵌套Book对象的最佳反序列化实现方式是什么?
解决方案
不需要为BookList编写自定义反序列化器,问题仅出在嵌套的Book对象字段补全逻辑上,只需要针对Book类处理即可,以下是两种实用的实现方式:
方式一:自定义Book反序列化器(以Jackson为例)
编写针对Book类的反序列化器,在解析时判断description字段是否存在,不存在则用title值填充:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; public class BookDeserializer extends JsonDeserializer<Book> { @Override public Book deserialize(JsonParser parser, DeserializationContext context) throws IOException { JsonNode node = parser.getCodec().readTree(parser); String title = node.get("title").asText(); // 判断description是否存在,不存在则复用title的值 String description = node.has("description") ? node.get("description").asText() : title; // 实例化Book的具体实现类(需自行定义继承自Book抽象类的BookImpl) return new BookImpl(title, description); } }
然后在Book抽象类上添加注解指定该反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = BookDeserializer.class) public abstract class Book { public abstract String title; public abstract String description; }
方式二:使用@JsonSetter注解简化逻辑(需配合具体实现类)
如果Book有对应的具体实现类并提供setter方法,可以通过@JsonSetter在赋值时处理字段补全:
// Book的具体实现类示例 public class BookImpl extends Book { private String title; private String description; @Override public String title() { return title; } @Override public String description() { return description; } @JsonSetter public void setTitle(String title) { this.title = title; // 如果description未赋值,用title填充 if (this.description == null) { this.description = title; } } @JsonSetter public void setDescription(String description) { this.description = description; } }
这种方式更简洁,但依赖具体实现类的setter逻辑,适合非纯抽象类的场景。
内容的提问来源于stack exchange,提问作者PBandJ
相关产品推荐
相关产品推荐

