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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:13:11