Java JSON反序列化时如何将id引用转换为对应实体类实例
以下是使用主流Jackson JSON库实现该需求的完整方案:
前置依赖(Maven示例)
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency>
实现步骤
核心逻辑是先预加载所有User实体到ID缓存,再通过自定义反序列化器将JSON中roles字段的用户ID自动映射为对应User实例。
1. 编写自定义反序列化器
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class UserMapDeserializer extends StdDeserializer<Map<String, User>> { // 存储userId与User实例的映射缓存 private final Map<String, User> userCache; public UserMapDeserializer() { this(new HashMap<>()); } public UserMapDeserializer(Map<String, User> userCache) { super(Map.class); this.userCache = userCache; } @Override public Map<String, User> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 先读取原始的<String,String>类型roles映射 Map<String, String> rawRoleMap = p.readValueAs(Map.class); Map<String, User> resultMap = new HashMap<>(); // 遍历转换为<String,User>类型映射 for (Map.Entry<String, String> entry : rawRoleMap.entrySet()) { resultMap.put(entry.getKey(), userCache.get(entry.getValue())); } return resultMap; } }
2. 修改POJO类补充必要方法
// Account类 import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import java.util.HashMap; import java.util.Map; public class Account { private String name; @JsonDeserialize(using = UserMapDeserializer.class) private Map<String, User> roles = new HashMap<>(); // 以下为Jackson反序列化必填的getter、setter,也可直接用Lombok的@Data注解生成 public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<String, User> getRoles() { return roles; } public void setRoles(Map<String, User> roles) { this.roles = roles; } }
// User类 public class User { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
3. 测试运行代码
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; public class DeserializeTest { public static void main(String[] args) throws Exception { ObjectMapper objectMapper = new ObjectMapper(); // 第一步:预加载所有User数据构建缓存 String user1Json = "{\"name\": \"Bob\",\"id\": \"user-1\"}"; String user2Json = "{\"name\": \"Alice\",\"id\": \"user-2\"}"; User user1 = objectMapper.readValue(user1Json, User.class); User user2 = objectMapper.readValue(user2Json, User.class); Map<String, User> userCache = new HashMap<>(); userCache.put(user1.getId(), user1); userCache.put(user2.getId(), user2); // 第二步:注册自定义反序列化器到ObjectMapper objectMapper.registerModule(new com.fasterxml.jackson.databind.module.SimpleModule() .addDeserializer(Map.class, new UserMapDeserializer(userCache))); // 第三步:反序列化Account数据 String accountJson = "{\n" + " \"name\" : \"Bob's Account\",\n" + " \"roles\": {\n" + " \"administrator\" : \"user-1\",\n" + " \"owner\" : \"user-1\",\n" + " \"participant\" : \"user-2\" \n" + " }\n" + "}"; Account account = objectMapper.readValue(accountJson, Account.class); // 结果验证 System.out.println(account.getRoles().get("administrator").getName()); // 输出Bob System.out.println(account.getRoles().get("participant").getName()); // 输出Alice } }
内容的提问来源于stack exchange,提问作者Vaan
相关产品推荐
相关产品推荐

