Spring Boot Camel带ZonedDateTime的JSON列表反序列化问题
问题场景
我有两条不同的Camel路由:
- 单个对象反序列化路由:
from(...).routeId(...) .unmarshal().json(SomeClass.class) ....;
- 列表对象反序列化路由:
from(...).routeId(...) .unmarshal(new ListJacksonDataFormat(SomeOtherClass.class)) ....;
SomeClass和SomeOtherClass均包含java.time.ZonedDateTime类型的timestamp字段。第一条路由处理单个对象时反序列化正常,但第二条路由处理对象列表时失败,报错:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type
java.time.ZonedDateTimenot supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
问题解答
1. 反序列化列表是否必须使用ListJacksonDataFormat?
不是必须,但ListJacksonDataFormat是Camel为列表反序列化提供的专用封装,使用起来更简洁直观。
你也可以通过JacksonDataFormat结合TypeReference来实现列表反序列化,代码示例:
.unmarshal().json(new JacksonDataFormat(new TypeReference<List<SomeOtherClass>>() {}))
这种方式同样可以完成列表的反序列化,后续也能正常传递给接收List参数的bean方法。
2. 是否必须引入jackson-datatype-jsr310模块?
第一条路由能正常处理ZonedDateTime,大概率是因为unmarshal().json(Class)背后使用的Jackson配置已经自动注册了JSR310模块(比如项目依赖间接引入、Camel Jackson组件默认配置等),但ListJacksonDataFormat默认没有复用这个配置,导致日期类型处理失败。
有两种解决方式:
- 方案一:引入官方依赖(推荐)
添加com.fasterxml.jackson.datatype:jackson-datatype-jsr310依赖到项目中,这是Jackson处理Java 8日期类型的标准解决方案,引入后ListJacksonDataFormat会自动识别并使用该模块。 - 方案二:手动注册JSR310模块
如果你不想新增依赖,可以手动给ListJacksonDataFormat配置的ObjectMapper注册JavaTimeModule:
另外,如果项目中已有预先配置好(已注册JSR310模块)的ListJacksonDataFormat format = new ListJacksonDataFormat(SomeOtherClass.class); format.getObjectMapper().registerModule(new JavaTimeModule()); // 在路由中使用该格式化器 from(...).routeId(...) .unmarshal(format) .bean(...,, "method");ObjectMapper,也可以直接将其传入ListJacksonDataFormat:ListJacksonDataFormat format = new ListJacksonDataFormat(SomeOtherClass.class); format.setObjectMapper(yourPreConfiguredObjectMapper);
内容的提问来源于stack exchange,提问作者u4963840

