Spring boot Spring与Jackson ObjectMapper和Java 8 Time(JSR-310)的集成
我正在努力配置Spring Integration DSL transformers使用的“定制”ObjectMapper。 我收到一个Spring boot Spring与Jackson ObjectMapper和Java 8 Time(JSR-310)的集成,spring-boot,jackson,spring-integration,spring-dsl,Spring Boot,Jackson,Spring Integration,Spring Dsl,我正在努力配置Spring Integration DSL transformers使用的“定制”ObjectMapper。 我收到一个java.time.Instantjson表示,我想将其解析为对象属性。i、 e: {“类型”:“测试”,“源”:“测试”,“时间戳”:{“epochSecond”:1454503381,“nano”:335000000} 这条消息是一条卡夫卡消息,它提出了一个问题:我是否应该编写一个实现卡夫卡编码器/解码器的自定义序列化程序,以便能够将卡夫卡消息转换为正确的对
java.time.Instant
json表示,我想将其解析为对象属性。i、 e:{“类型”:“测试”,“源”:“测试”,“时间戳”:{“epochSecond”:1454503381,“nano”:335000000} 这条消息是一条卡夫卡消息,它提出了一个问题:我是否应该编写一个实现卡夫卡编码器/解码器的自定义序列化程序,以便能够将卡夫卡消息转换为正确的对象,或者spring integration必须自动执行此操作 fw/依赖项和版本:
弹簧靴-1.3.2.释放
Spring集成JavaDSL-1.1.1.RELEASE
FasterXml Jackson-2.6.5
我根据Jackson文档将此Java配置添加到项目中: 分辨率:
问题是,我预计Spring将检测jackson-datatype-jsr310原型并注册JavaTimeModule,但事实并非如此,这是完全正确的。 有两种方法可以解决此问题:
1.如果我们按原样使用Spring Boot和Spring集成,这是公认的答案。
2.如果使用Spring集成Dsl,只需将IntegrationConfiguration类与jsonObjectMapper()bean保持在一起,并像这样使用它:
@Autowired
private JsonObjectMapper jsonObjectMapper;
return IntegrationFlows
.from(inboundChannel())
.transform(Transformers.fromJson(myDto.class, jsonObjectMapper))
...
您是否为通道适配器定义了编码器 您应该始终为正在使用的适配器(入站通道适配器或消息驱动器通道适配器)使用编码器 在您的情况下,StringEncoder应该可以解决这个问题
<bean id="myEncoder" class="org.springframework.integration.kafka.serializer.common.StringEncoder"/>
强制Spring Integration使用Spring Boot与此无关 您只需使用
jsonObjectMapper()
配置jsonObjectTransformer
:
尽管没有理由将
JsonObjectMapper
注册为bean。在将“timestamp”更改为java.time.Instant之前,一切都很顺利。我必须单独测试组件并隔离问题…我还没有使用JavaTimeModule
,但是您是否介意确保我们确实使用jsonObjectMapper()
来定义JSONObjectTransformer
?从另一方面看,我没有看到任何关于这种即时表示的测试:我解决了问题,得到了以下结果。由于某些原因,没有考虑JavaTimeModule。第二个问题是,我已经测试了java.time.Instant的默认json表示形式,但它不同(正确:“timestamp”:1454514333.855000000)。我认为这无关紧要。他从Kafka接收正常的JSON字符串,并尝试将其反序列化到POJO,但由于Instant
ctor问题而失败。很好。10倍多。我试图定义JSONtobjectTransformer,但我不知道@Transformer注释。10x再有,请参阅Spring集成参考手册中的更多内容:并注意Spring集成Java DSL:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class java.time.Instant]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: {"type":"TEST","source":"TEST","timestamp":{"epochSecond":1454503381,"nano":335000000}}; line: 1, column: 71] (through reference chain: my.app.MyDto["timestamp"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1106)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:296)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2764)
at org.springframework.integration.support.json.Jackson2JsonObjectMapper.fromJson(Jackson2JsonObjectMapper.java:75)
at org.springframework.integration.support.json.Jackson2JsonObjectMapper.fromJson(Jackson2JsonObjectMapper.java:44)
at org.springframework.integration.support.json.AbstractJacksonJsonObjectMapper.fromJson(AbstractJacksonJsonObjectMapper.java:56)
at org.springframework.integration.json.JsonToObjectTransformer.doTransform(JsonToObjectTransformer.java:78)
at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33)
... 74 more
@Autowired
private JsonObjectMapper jsonObjectMapper;
return IntegrationFlows
.from(inboundChannel())
.transform(Transformers.fromJson(myDto.class, jsonObjectMapper))
...
<bean id="myEncoder" class="org.springframework.integration.kafka.serializer.common.StringEncoder"/>
@Bean
@Transformer(inputChannel="input", outputChannel="output")
JsonToObjectTransformer jsonToObjectTransformer() {
return new JsonToObjectTransformer(jsonObjectMapper());
}