2

Spring Integration DSL トランスフォーマーで使用される「カスタム」 ObjectMapper の構成に苦労しています。java.time.Instantオブジェクトのプロパティに解析したい json 表現を受け取りました。例:
{"type": "TEST", "source":"TEST", "timestamp":{"epochSecond": 1454503381, "nano": 335000000}}

メッセージは、質問を提起するカフカ メッセージです: カフカ メッセージを適切なオブジェクトに変換できるようにするために、カフカ エンコーダー/デコーダーを実装するカスタム シリアライザーを作成する必要がありますか、それともスプリング統合でこれを自動的に行う必要がありますか?

fw/依存関係とバージョン:
Spring Boot - 1.3.2.RELEASE
Spring Integration Java Dsl - 1.1.1.RELEASE
FasterXml Jackson - 2.6.5

Jackson のドキュメントに従って、この Java 構成をプロジェクトに追加しました: 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 アーティファクト:

<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

これは私が得た例外です:

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 アーキタイプを検出し、JavaTimeModule を登録することを期待していたことですが、そうではなく、まったく問題ありません。これを修正する方法は 2 つあります
。 1. Spring Boot を Spring Integration でそのまま使用する場合の受け入れられた答え。
2. Spring Integration Dsl を使用する場合は、IntegrationConfiguration クラスを jsonObjectMapper() Bean とともに保持し、次のように使用します。

@Autowired
private JsonObjectMapper jsonObjectMapper;    

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

2 に答える 2

2

Spring Integration にそれを強制的に使用させるという問題について、Spring Boot とは何の関係もありません。

JsonToObjectTransformerそれを使用して構成する必要があるだけですjsonObjetMapper()

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

JsonObjectMapperBean として登録する理由はありませんが。

于 2016-02-03T16:39:12.720 に答える