如何反序列化属性值为序列化JSON串的数据并映射到自定义POJO类
解决方案
核心问题梳理
你需要同时处理两个映射逻辑:
- 原始JSON的
Id字段需要映射到Event类的MessageId属性,字段名不匹配需要单独配置 - 原始JSON的
Message字段是转义后的JSON数组字符串,需要二次反序列化为List<Item>类型
实现方案
方案1:使用Jackson实现(Java生态主流方案)
- 给
Event类添加注解配置映射规则
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public class Event { private String Type; // 映射原始JSON的Id字段 @JsonProperty("Id") private String MessageId; // 指定自定义反序列化器处理嵌套JSON字符串 @JsonDeserialize(using = MessageListDeserializer.class) private List<Item> Message; // 此处省略getter、setter方法 }
- 实现
Message字段的自定义反序列化器
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.List; public class MessageListDeserializer extends StdDeserializer<List<Item>> { private static final ObjectMapper objectMapper = new ObjectMapper(); public MessageListDeserializer() { super(List.class); } @Override public List<Item> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { // 读取原始的JSON字符串内容 String nestedJsonStr = jsonParser.getText(); // 二次反序列化为List<Item> return objectMapper.readValue(nestedJsonStr, new TypeReference<List<Item>>() {}); } }
- 给
Item类添加忽略未知字段的注解,避免不存在的LineNo字段导致反序列化报错
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public class Item { private String CarNo; private String TransactionNo; private String ReceiptNo; private String LineNo; private String Date; private String Time; // 此处省略getter、setter方法 }
- 调用反序列化代码
ObjectMapper objectMapper = new ObjectMapper(); Event event = objectMapper.readValue("你的原始JSON字符串", Event.class);
方案2:使用Fastjson实现
- 给
Event类添加注解配置
import com.alibaba.fastjson.annotation.JSONField; public class Event { private String Type; // 映射原始JSON的Id字段 @JSONField(name = "Id") private String MessageId; // 指定自定义反序列化器 @JSONField(deserializeUsing = MessageListDeserializer.class) private List<Item> Message; // 此处省略getter、setter方法 }
- 实现自定义反序列化器
import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import com.alibaba.fastjson.JSON; import java.lang.reflect.Type; import java.util.List; public class MessageListDeserializer implements ObjectDeserializer { @Override public List<Item> deserialze(DefaultJSONParser parser, Type type, Object fieldName) { String nestedJsonStr = parser.parseObject(String.class); return JSON.parseArray(nestedJsonStr, Item.class); } @Override public int getFastMatchToken() { return com.alibaba.fastjson.parser.JSONToken.LITERAL_STRING; } }
- 调用反序列化代码
Event event = JSON.parseObject("你的原始JSON字符串", Event.class);
简易方案:手动二次反序列化(无需自定义反序列化器)
如果不想写自定义反序列化器,可以先做外层反序列化,再手动转换Message字段:
- 定义临时中间类接收外层参数
public class TempEvent { private String Type; @JsonProperty("Id") private String MessageId; private String Message; // 此处省略getter、setter方法 }
- 手动转换逻辑
ObjectMapper objectMapper = new ObjectMapper(); // 第一步:先反序列化外层为临时对象 TempEvent tempEvent = objectMapper.readValue("你的原始JSON字符串", TempEvent.class); // 第二步:手动转换Message字段 List<Item> items = objectMapper.readValue(tempEvent.getMessage(), new TypeReference<List<Item>>() {}); // 组装最终Event对象 Event event = new Event(); event.setType(tempEvent.getType()); event.setMessageId(tempEvent.getMessageId()); event.setMessage(items);
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

