如何从包含嵌套JSON字符串的JSON生成POJO?
解决嵌套JSON字符串转POJO的问题
首先得明确你的问题核心:请求体里的message字段不是直接的嵌套JSON对象,而是序列化后的JSON字符串(看它外层包了引号,内部双引号还做了转义),所以常规的Jackson自动映射会把它当成普通字符串,没法直接转成结构化的POJO。下面给你两种实用的解决思路:
方法一:自定义反序列化器(推荐,更优雅)
这种方式能让Jackson自动帮你完成「JSON字符串→POJO」的转换,不需要手动拆分步骤。
1. 先拆分所有需要的POJO类
先把message里的嵌套结构拆成独立实体:
// SysData.java @JsonIgnoreProperties(ignoreUnknown = true) public class SysData { private long time; private Data data; // 记得生成无参构造器、getter和setter } // Data.java @JsonIgnoreProperties(ignoreUnknown = true) public class Data { private String appUUID; private String userId; // 生成无参构造器、getter和setter } // AppData.java @JsonIgnoreProperties(ignoreUnknown = true) public class AppData { private String testMessage; private String ackURL; // 生成无参构造器、getter和setter } // Message.java,对应message字段的结构化内容 @JsonIgnoreProperties(ignoreUnknown = true) public class Message { private SysData sysData; private AppData appData; // 生成无参构造器、getter和setter }
然后定义外层的实体类,重点处理message字段:
// Device.java @JsonIgnoreProperties(ignoreUnknown = true) public class Device { // 映射JSON里的"device-id"字段 @JsonProperty("device-id") private int deviceId; // 生成无参构造器、getter和setter } // Client.java @JsonIgnoreProperties(ignoreUnknown = true) public class Client { private Device device; // 生成无参构造器、getter和setter } // 核心的EventBody类,给message字段指定自定义反序列化器 @JsonIgnoreProperties(ignoreUnknown = true) public class EventBody { // 告诉Jackson用自定义的解析器处理这个字段 @JsonDeserialize(using = MessageDeserializer.class) private Message message; private Client client; // 生成无参构造器、getter和setter }
2. 实现自定义反序列化器
写一个MessageDeserializer,负责把JSON字符串转成Message对象:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class MessageDeserializer extends JsonDeserializer<Message> { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public Message deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 先读取message字段的字符串内容 String messageJson = p.getText(); // 把字符串反序列化成Message对象 return objectMapper.readValue(messageJson, Message.class); } }
这样配置后,当你用Jackson解析请求体时,会自动把message的JSON字符串转成Message对象,直接调用eventBody.getMessage()就能拿到结构化数据了。
方法二:手动拆分解析(适合简单场景)
如果不想写自定义反序列化器,也可以分两步走:先解析外层拿到message的字符串,再手动把字符串转成POJO。
1. 定义临时外层POJO
@JsonIgnoreProperties(ignoreUnknown = true) public class TempEventBody { // 先把message当成字符串接收 private String message; private Client client; // 生成无参构造器、getter和setter }
2. 分两步完成解析
ObjectMapper objectMapper = new ObjectMapper(); // 第一步:解析外层结构,拿到message的JSON字符串 TempEventBody tempEvent = objectMapper.readValue(requestBody, TempEventBody.class); // 第二步:把message字符串解析成Message对象 Message message = objectMapper.readValue(tempEvent.getMessage(), Message.class); // 最后组装成目标EventBody对象 EventBody eventBody = new EventBody(); eventBody.setMessage(message); eventBody.setClient(tempEvent.getClient());
这种方式代码更直白,但会显得零散,适合偶尔处理这类场景。
注意事项
- 确保项目已引入Jackson核心依赖(比如
com.fasterxml.jackson.core:jackson-databind) - 所有POJO类必须有无参构造器,Jackson默认依赖它创建对象
- 字段名和JSON键不一致时,用
@JsonProperty注解做映射(比如device-id对应deviceId)
内容的提问来源于stack exchange,提问作者Kammryn Dancy
相关产品推荐
相关产品推荐

