如何在 JSON 反序列化期间将引用转换为实例

Posted

技术标签:

【中文标题】如何在 JSON 反序列化期间将引用转换为实例【英文标题】:How to convert references into instances during JSON deserialization 【发布时间】:2022-01-11 16:54:49 【问题描述】:

这是一个问题,但已解决。我试图将一些 JSON 数据反序列化为 Java POJO。比如下面的 JSON 数据:

对于 Account 数据,我有以下 JSON 数据,它们通过 id 引用用户:


  "name" : "Bob's Account",
  "roles": 
    "administrator" : "user-1",
    "owner"         : "user-1",
    "participant"   : "user-2" 
  

对于Users 'Bob' 和 'Alice' 我有这个 JSON 数据:


  "name": "Bob",
  "id"  : "user-1"


  "name": "Alice",
  "id"  : "user-2"

我想要实现的是将数据反序列化为以下 Java 类:

import java.util.Map;
import java.util.HashMap;

public class Account 
  String name;
  Map<String, User> roles = new HashMap<>();

public class User 
  String id;
  String name;

请注意,Account 类有一个将 String 链接到 User 实例的映射。

【问题讨论】:

请添加用于反序列化 json 输入的代码。您是否使用正确的方法 readValue?我认为您的注释应该有 converter=... 而不是 contentConverter=... 嗨@TomElias,我已经添加了它并找出了我的错误。我在问题中给出的示例是我的实际代码的简化版本,事实证明,我有另一个需要类似转换器的属性。但我想一次实现一个......感谢您的支持和抱歉互联网 请将解决方案添加为答案并接受它或删除问题。谢谢! @JoãoDias,考虑完成 【参考方案1】:

为此,您必须在Account 对象中注释属性roles,如下所示:

  ⋯snip⋯
  @JsonDeserialize(contentConverter = UserReferenceConverter.class)
  Map<String, User> roles = new HashMap<>();
  ⋯snip⋯

然后创建一个UserReferenceConverter,它可以将String 形式的用户ID 转换为实际的User instanceenter code here

public class UserReferenceConverter extends StdConverter<String, User> 
  
  @Override
  public User convert( String value ) 
    // Get the user...
    return UserRepository.getUserById( value );
  

要从 JSON 字符串加载 Account,请运行以下命令:

import com.fasterxml.jackson.databind.ObjectMapper;

  ⋯snip⋯
  ObjectMapper mapper = new ObjectMapper();
  Account account = mapper.readValue(json, Account.class);
  ⋯snip⋯

【讨论】:

以上是关于如何在 JSON 反序列化期间将引用转换为实例的主要内容,如果未能解决你的问题,请参考以下文章

JSON转换和序列化的区别

序列化和json

在 JSON 反序列化期间没有为“System.String”类型定义无参数构造函数

JSON中的反序列化和序列化是啥?

如何正确使用javascript反序列化将json字符串转换为复杂对象?

C#反序列化Json字符串