与Jackson ObjectMapper和Java 8 Time的Spring集成(JSR-310) [英] Spring Integration with Jackson ObjectMapper and Java 8 Time (JSR-310)

查看:648
本文介绍了与Jackson ObjectMapper和Java 8 Time的Spring集成(JSR-310)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力配置Spring Integration DSL变换器使用的自定义ObjectMapper。
我收到一个 java.time.Instant json表示我想要解析为对象属性。即:

{type:TEST,source:TEST,timestamp:{epochSecond:1454503381,nano:335000000}}

I am struggling with configuring a "custom" ObjectMapper to be used by the Spring Integration DSL transformers. I receive an java.time.Instant json representations that I would like to parse to object properties. i.e:
{"type": "TEST", "source":"TEST", "timestamp":{"epochSecond": 1454503381, "nano": 335000000}}

该消息是一条kafka消息,它提出了一个问题:我是否应该编写一个实现Kafka编码器/解码器的自定义序列化器,以便能够将kafka消息转换为正确的对象或spring-integration必须自动执行此操作?

The message is a kafka message which raises a question: Should I write a custom serializer implementing Kafka encoders/decoders in order to be able to transform the kafka message to the right object or spring-integration have to do this automatically?

fw / dependencies和version:

Spring Boot - 1.3.2.RELEASE

Spring Integration Java Dsl - 1.1.1.RELEASE

FasterXml Jackson - 2.6.5

fw/dependencies and version:
Spring Boot - 1.3.2.RELEASE
Spring Integration Java Dsl - 1.1.1.RELEASE
FasterXml Jackson - 2.6.5

我添加了这个Java根据Jackson文档配置项目:
https://github.com/FasterXML/ jackson-datatype-jsr310

I've added this Java Configuration to the project following the Jackson documentation: https://github.com/FasterXML/jackson-datatype-jsr310

@Configuration
public class IntegrationConfiguration {

    @Bean
    public JsonObjectMapper<JsonNode, JsonParser> jsonObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        return new Jackson2JsonObjectMapper(mapper);
    }
}

以及以下Jackson JSR-310文物:

and the following Jackson JSR-310 artefact as well:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.6.5</version>
</dependency>

根据Spring博客上的这篇文章,我甚至不需要注册新的Java8时间模块。
https:/ /spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring#jackson-modules

Based on this post on the Spring blog I don't even have to register the new Java8 time module. https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring#jackson-modules

这是我得到的例外:

This is the exception I got:

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

解决方案:

问题是我期望Spring会检测到jackson-datatype-jsr310原型并注册JavaTimeModu le,但它并不完全没问题。
有两种方法我们可以解决这个问题:

1.如果我们按原样使用Spring Boot与Spring Integration一起接受答案。

2.如果使用Spring Integration Dsl,只需将IntegrationConfiguration类与jsonObjectMapper()bean保持一致并使用它:

RESOLUTION:
The problem was that I expected that Spring will detect the jackson-datatype-jsr310 archetype and register the JavaTimeModule, but it doesn't which is totally fine. There are two way we can fix this:
1. The accepted answer if we use Spring Boot with Spring Integration as is.
2. If using the Spring Integration Dsl, just keep the IntegrationConfiguration class with the jsonObjectMapper() bean and use it like that:

@Autowired
private JsonObjectMapper jsonObjectMapper;    

return IntegrationFlows
        .from(inboundChannel())
        .transform(Transformers.fromJson(myDto.class, jsonObjectMapper))
        ...


推荐答案

关于强制Spring的问题与Spring Boot无关集成使用它。

There is nothing to do with the Spring Boot on the matter to force Spring Integration to use that.

你只需配置 JsonToObjectTransformer ,你的 jsonObjetMapper()

@Bean
@Transformer(inputChannel="input", outputChannel="output")
JsonToObjectTransformer jsonToObjectTransformer() {
    return new JsonToObjectTransformer(jsonObjectMapper());
}

虽然没有理由注册 JsonObjectMapper 作为一个bean。

Although there is no reason to register JsonObjectMapper as a bean.

这篇关于与Jackson ObjectMapper和Java 8 Time的Spring集成(JSR-310)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆