使用 Gson 反序列化 JSON 时引用父对象

2024-04-24

给定以下 JSON:

{
    "authors": [{
        "name": "Stephen King",
        "books": [{
            "title": "Carrie"
        }, {
            "title": "The Shining"
        }, {
            "title": "Christine"
        }, {
            "title": "Pet Sematary"
        }]
    }]
}

这个对象结构:

public class Author {
    private List<Book> books;
    private String name;
}

public class Book {
    private transient Author author;
    private String title;
}

有没有办法使用 Google Java 库 Gson 来反序列化 JSON,并且 books 对象具有对“父”作者对象的引用?

是否可以without使用自定义解串器?

  • 如果是:如何?
  • 如果不是:是否仍然可以使用自定义解串器来完成此操作?

在这种情况下,我将实现一个自定义JsonDeserializer为父对象,并传播Author信息,像这样:

public class AuthorDeserializer implements JsonDeserializer<Author> {
    @Override
    public Author deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        final JsonObject authorObject = json.getAsJsonObject();

        Author author = new Author();
        author.name = authorObject.get("name").getAsString();

        Type booksListType = new TypeToken<List<Book>>(){}.getType();
        author.books = context.deserialize(authorObject.get("books"), booksListType);

        for(Book book : author.books) {
            book.author = author;
        }

        return author;
    }   
}

请注意,我的示例省略了错误检查。你会像这样使用它:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Author.class, new AuthorDeserializer())
    .create();

为了展示它的工作原理,我只从示例 JSON 中提取了“authors”键,这样我就可以执行以下操作:

JsonElement authorsJson  = new JsonParser().parse(json).getAsJsonObject().get("authors");

Type authorList = new TypeToken<List<Author>>(){}.getType();
List<Author> authors = gson.fromJson(authorsJson, authorList);
for(Author a : authors) {
    System.out.println(a.name);
    for(Book b : a.books) {
        System.out.println("\t " + b.title + " by " + b.author.name);
    }
}

其中打印:

Stephen King
     Carrie by Stephen King
     The Shining by Stephen King
     Christine by Stephen King
     Pet Sematary by Stephen King
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Gson 反序列化 JSON 时引用父对象 的相关文章

随机推荐

  • 为什么我不能在 python 的 for 循环中重新分配变量? [复制]

    这个问题在这里已经有答案了 今天我发现一个有趣的事实 我无法在 for 循环 中重新分配变量 但为什么呢 这是我的代码 gt gt gt my list 1 2 3 4 5 gt gt gt for i in my list gt gt g
  • WCF - 如何在 JSON 中序列化和反序列化?

    我在 WCF 中编写了几个类 数据契约和服务契约 并且尝试在 JSON 中进行序列化和反序列化 如果我需要以下 JSON 结构 我将如何创建 DataContract s response locations location id 12
  • 在 JavaScript 中查找文本字符串

    我有一个很大的有效 JavaScript 文件 utf 8 我需要从中自动提取所有文本字符串 为简单起见 该文件不包含任何注释块 仅包含有效的 ES6 JavaScript 代码 一旦我发现发生 or 或 我应该扫描文本块的末尾 这是我陷入
  • TypeError:expect(...).to.startsWith 不是一个函数 - chai 和 chakram

    我开始编写一些自动化测试 API 现在我尝试对此端点执行以下操作 https dog ceo api breeds image random https dog ceo api breeds image random 所以我添加到我的函数中
  • Java (JGIT) Files.delete() 删除文件失败,但 file.delete() 成功

    我正在使用 jgit 版本4 8 0 201706111038 r 并添加一个关闭钩子以在终止后删除临时目录 但是 关闭挂钩无法从内部删除某些文件 git子目录 尽管按照 jgit 的要求关闭了 Git 对象 但有趣的是 只有当我使用 Pa
  • 多次运行 gradle 任务

    我有一个 gradle 项目 在子目录中包含两个模块 目录结构如下 root module1 build gradle module2 build gradle build gradle settings gradle 顶层settings
  • 如何修复 getActionBar 方法可能产生 java.lang.NullPointerException

    我在活动中使用工具栏作为操作栏 我正在尝试添加方法getActionBar setDisplayHomeAsUpEnabled true 到 Activity java 文件 用于旧设备的向上导航 该方法在 Android Studio 中
  • 在反序列化之前根据标头过滤消息

    有时 可以在反序列化之前根据标头值过滤掉消息 使用 spring kafka 是否有针对此场景的任何现有模式 我正在考虑实现类似于 ErrorHandlingDeserializer 除了委托之外还将过滤谓词作为属性 有什么建议么 谢谢 是
  • MVC 5 中的存储过程不返回值

    我正在通过数据库方法使用实体框架 MVC5 进行工作 我使用Mysql作为数据库 我创建一个程序 当通话流程在Mysql中它按照我的预期工作 但是当我在 MVC 中使用过程时 它每次都会返回 0 储存程序 CREATE PROCEDURE
  • .playground 是 swift 文件吗?谁能“看到”它?

    我试图弄清楚 playground 文件到底是什么 如果它是源文件 则项目中的其他 swift 文件或其他 playground 文件都无法 据我尝试 看到它 反之亦然 一个项目应该有一个这样的文件吗 它们是一种 swift 文件吗 我知道
  • Boost 库构建 - 运行时链接和链接选项之间的区别

    我正在尝试使用 MSVC VS 2010 在 Windows 7 中构建 boost 库 我遇到过这些选择运行时链接和链接在 bjam 命令行选项中 我想知道它们是如何使用的以及它们之间的确切区别是什么 我已经使用此命令行构建了 Boost
  • 使用 Google Breakpad 的小型转储无法显示应用程序崩溃的行号

    我在崩溃时获得了应用程序的小型转储文件 但它没有给我诸如函数名称和行号之类的详细信息 输出如下 Operating system Linux 0 0 0 Linux 3 3 8 2 2 1 SMP Thu May 12 13 30 26 U
  • 如何实现 hamcrest 匹配器

    我想运行这行代码 assertThat contextPin get equalTo pinPage getPinObjFromUi 但我想打印到日志中以提供信息 这意味着我可以知道哪些字段不相等 所以我想到了实现一个匹配器 我用谷歌搜索过
  • 如何更改默认的 javadoc 样式表?

    是否有命令行选项来更改 javadoc 创建的样式表文件 我想使用我自己的 css 文件 默认的蓝色很无聊 我尝试了 stylesheet 选项 但不支持它 是的 这是可能的 而且实际上非常简单 例如 如果您查看 Mockito 的 jav
  • Markdown 所见即所得编辑器和预览在同一文本区域中[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我寻找一个编辑器来编写 Markdown 语法并在同一文本区域中预览 例如引导所见即所得HTML5 ht
  • Django Crispy-forms - 自定义按钮

    我的 django crispy form 中有两个按钮 self helper add input Submit submit Submit self helper add input Button cancel Cancel 提交按钮工
  • !r 在 str() 和 repr() 中做什么?

    根据Python 2 7 12 文档 https docs python org 2 tutorial inputoutput html fancier output formatting s apply str and r apply r
  • 预加载背景图像

    我正在构建一个循环显示 3 个不同背景的页面 每 750 毫秒更改一次 为此 我在主体中添加了一个带有相关背景图像的类 并使用 JS 进行了更改 对于第一次循环 它们会闪烁 因为图像必须加载 所以它不会立即出现 因此 我可以使用任何方法来预
  • 使用#selector 传递参数

    我是 Swift 的初学者 我正在尝试通过通知中心启动一个功能 ViewController swift 中的观察者调用函数reload override func viewDidLoad super viewDidLoad Notific
  • 使用 Gson 反序列化 JSON 时引用父对象

    给定以下 JSON authors name Stephen King books title Carrie title The Shining title Christine title Pet Sematary 这个对象结构 publi