3

我正在使用集成流来调用 RESTful Web 服务,如下所示:

@Bean
IntegrationFlow flow() throws Exception {
    return IntegrationFlows.from("inputChannel")
            .handle(Http.outboundGateway("http://provider1.com/...")
                    .httpMethod(HttpMethod.GET)
                    .expectedResponseType(ItemDTO[].class))
            .get();
}

事实上,上面的代码完美运行。正如我从文档中了解到的,Spring 集成的 http outbound-gateway 使用 RestTemplate 的实例将 Http 响应正文转换为 s 数组ItemDTO

现在让我们考虑以下代码:

@Bean
IntegrationFlow flow() throws Exception {
    return IntegrationFlows.from("inputChannel")
            .handle(Http.outboundGateway("http://provider2.com/...")
                    .httpMethod(HttpMethod.GET)
                    .expectedResponseType(String.class))
            .<String,String>transform(m -> sirenToHal(m))
            .transform(Transformers.fromJson(ItemDTO[].class))
            .get();
}

在这种情况下,Http 响应体被转换成一个字符串,它被传递给一个转换器(例如在我的实际项目中,我使用JOLT从一个警报文档转换为一个 HAL——JSON 资源表示)。然后,我实例化一个转换器来处理 JSON 到 java 对象的映射。令人惊讶的是,上面的代码失败了(例如,在我的项目中,转换器抛出 a UnrecognizedPropertyException)。

失败的原因似乎是transformer使用的Object mapper没有和RestTemplate一样配置。我想知道为什么转换器不使用与 RestTemplate 实例相同的 ObjectMapper,或者至少为什么它们不使用相同的配置(即 Spring boot 的全局配置)。无论如何,有没有配置 ObjectMapper 供转换器使用?

更新

我发现了如何配置变压器的对象映射器。

首先,我们创建并配置Jackson的ObjectMapper的一个实例,如下:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// + any other additional configuration setting

然后,我们按如下方式实例化转换器(替换上面代码中的相应行):

.transform(Transformers.fromJson(ItemDTO[].class, new Jackson2JsonObjectMapper(mapper)))

我还是觉得transformer使用的ObjectMapper应该采用Spring boot的全局配置。

4

1 回答 1

1

这是一个有趣的观点,但由于您没有注入RestTemple,Http.outboundGateway()甚至, 我只看到Spring Integration 使用的和之间的MappingJackson2HttpMessageConverter区别just , 当 Spring Web 在其代码中执行此操作时:ObjectToJsonTransformerMappingJackson2HttpMessageConverternew ObjectMapper()

public MappingJackson2HttpMessageConverter() {
    this(Jackson2ObjectMapperBuilder.json().build());
}

即使 Spring Boot 自动配置ObjectMapperbean,我也看不到此硬代码对所有这些功能的任何引用。

所以,请确认Jackson2ObjectMapperBuilder.json().build()那里也适用于您,并随时提出JIRA票来协调 Spring IntegrationObjectMapper基础架构与 Spring Web。

更新

好的。在我看来,我发现了不同之处。我是对的 - Jackson2ObjectMapperBuilder

// Any change to this method should be also applied to spring-jms and spring-messaging
// MappingJackson2MessageConverter default constructors
private void customizeDefaultFeatures(ObjectMapper objectMapper) {
    if (!this.features.containsKey(MapperFeature.DEFAULT_VIEW_INCLUSION)) {
        configureFeature(objectMapper, MapperFeature.DEFAULT_VIEW_INCLUSION, false);
    }
    if (!this.features.containsKey(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
        configureFeature(objectMapper, DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }
}

因此,我们也必须将此选项应用于 Spring Integration。另请参阅MappingJackson2MessageConverter

JIRA 关于此事:https ://jira.spring.io/browse/INT-4001

于 2016-04-20T16:17:40.517 回答