如何用Jackson ObjectMapper解析含匿名与命名字段的JSON数组
解决Jackson解析数组型JSON的问题
问题背景
要解析的目标JSON是一个包含3个元素的数组:
["EVENT","event-id",{"content":"{}","created_at":1677781808,"tags":[["t","tag1"]]}]
当前使用的Event类仅定义了前两个字段的映射,解析时Jackson发现数组存在第三个未映射的对象元素,因此抛出错误:
Unexpected token (START_OBJECT), expected END_ARRAY: Unexpected JSON values; expected at most 2 properties (in JSON Array) at [Source: (byte[])"["EVENT","3c1dbf5f-b2b0-478d-9b18-2721a90d5f29",{"content":...
解决方案
1. 定义详情实体类
针对数组第三个元素的结构,创建EventDetails类来映射其字段:
public class EventDetails { private String content; @JsonProperty("created_at") // 匹配JSON中的下划线命名 private long createdAt; private List<List<String>> tags; // 生成getter、setter方法,或使用Lombok的@Data注解简化 }
2. 修改Event类映射完整数组元素
更新Event类,添加第三个字段并显式指定数组索引(避免字段顺序变化导致解析错误):
@JsonFormat(shape = JsonFormat.Shape.ARRAY) public class Event { @JsonProperty(index = 0) private String event; @JsonProperty(index = 1) private String eventId; @JsonProperty(index = 2) private EventDetails details; @Override public String toString() { ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); try { return mapper.writeValueAsString(this); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } // 生成getter、setter方法 }
3. 正常解析
原解析代码无需修改,现在Jackson会自动将数组的三个元素分别映射到event、eventId和details字段:
Event event = mapper.readValue(message.getPayload().getBytes(StandardCharsets.UTF_8), Event.class);
替代方案(不推荐)
如果不想定义实体类,也可以用Map<String, Object>接收第三个元素,但这种方式类型不安全,仅适合临时调试场景:
@JsonFormat(shape = JsonFormat.Shape.ARRAY) public class Event { @JsonProperty(index = 0) private String event; @JsonProperty(index = 1) private String eventId; @JsonProperty(index = 2) private Map<String, Object> details; // 其余代码不变 }
内容的提问来源于stack exchange,提问作者kerner1000
相关产品推荐
相关产品推荐

