简体   繁体   English

Spring Integration Java DSL - 如何配置JSON转换器以获取Spring引导的全局设置?

[英]Spring Integration Java DSL — How to configure the JSON transformer to take Spring boot's global settings?

I am using an integration flow to call a RESTful web service as follows: 我使用集成流来调用RESTful Web服务,如下所示:

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

In fact, the code above works perfectly. 事实上,上面的代码完美无缺。 As I understand from the documentation, Spring integration's http outbound-gateway uses an instance of RestTemplate to convert the Http response body to an array of ItemDTO s. 据我从文档中了解,Spring集成的http outbound-gateway使用RestTemplate实例将Http响应体转换为ItemDTO数组。

Let us now consider the following code: 现在让我们考虑以下代码:

@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();
}

In this case, the Http response body is converted into a String, which is passed to a transformer (eg in my actual project, I use JOLT to convert from a siren document to a HAL -- JSON resource representations). 在这种情况下,Http响应体被转换为String,并传递给变换器(例如,在我的实际项目中,我使用JOLT将警报器文档转换为HAL-JSON资源表示)。 Then, I instantiate a transformer to handle the mapping of JSON to java objects. 然后,我实例化一个转换器来处理JSON到java对象的映射。 Suprisingly, the code above fails (eg in my project, the transformer throws a UnrecognizedPropertyException ). 令人惊讶的是,上面的代码失败了(例如在我的项目中,变换器抛出了UnrecognizedPropertyException )。

The reason of the failure seems to be that the Object mapper used by the transformer is not configured in the same way as the RestTemplate. 失败的原因似乎是变换器使用的Object映射器的配置方式与RestTemplate不同。 I wonder why the transformer does not use the same ObjectMapper as the instance of RestTemplate or, at least, why they do not use the same configuration (ie Spring boot's global configuration). 我想知道为什么变换器不使用与RestTemplate实例相同的ObjectMapper,或者至少为什么它们不使用相同的配置(即Spring boot的全局配置)。 Anyway, is there anyway configure the ObjectMapper to be used by the transformer? 无论如何,是否有配置ObjectMapper供变压器使用?

Update 更新

I found out how to configure the tranformer's object mapper. 我找到了如何配置tranformer的对象映射器。

First, we create and configure an instance of Jackson's ObjectMapper, as follows: 首先,我们创建并配置Jackson的ObjectMapper实例,如下所示:

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

Then, we instantiate the transformer as follows (replacing the corresponding line in the code above): 然后,我们按如下方式实例化变换器(替换上面代码中的相应行):

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

I still think the ObjectMapper used by the transformer should take Spring boot's global configuration. 我仍然认为变换器使用的ObjectMapper应该采用Spring boot的全局配置。

That's an interesting point, but since you don't inject RestTemple into the Http.outboundGateway() , neither even MappingJackson2HttpMessageConverter , I only see difference between ObjectToJsonTransformer and MappingJackson2HttpMessageConverter , that Spring Integration uses just new ObjectMapper() , when the Spring Web does this in its code: 这是一个有趣的观点,但是由于你没有将RestTemple注入Http.outboundGateway() ,所以即使是MappingJackson2HttpMessageConverter ,我只看到ObjectToJsonTransformerMappingJackson2HttpMessageConverter之间的MappingJackson2HttpMessageConverter ,Spring Integration只使用new ObjectMapper() ,当Spring Web执行此操作时在其代码中:

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

Even if Spring Boot auto-configure ObjectMapper bean I don't see any reference from this hard code to all those feature. 即使Spring Boot自动配置ObjectMapper bean,我也没有看到从这个硬代码到所有这些功能的任何引用。

So, please, confirm that Jackson2ObjectMapperBuilder.json().build() works for you there, too and feel free to raise a JIRA ticket to harmonize the Spring Integration ObjectMapper infrastructure with Spring Web. 所以,请确认Jackson2ObjectMapperBuilder.json().build()可以在那里工作,并随意提出一个JIRA票证,以便将Spring Integration ObjectMapper基础架构与Spring Web协调一致。

UPDATE UPDATE

OK. 好。 Seems for me I found the difference. 似乎对我来说,我发现了差异。 And I was correct - Jackson2ObjectMapperBuilder : 我是对的 - 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);
    }
}

So, we have to apply this options to Spring Integration as well. 因此,我们也必须将此选项应用于Spring Integration。 Also see MappingJackson2MessageConverter . 另请参见MappingJackson2MessageConverter

The JIRA on the matter: https://jira.spring.io/browse/INT-4001 关于此事的JIRA: https//jira.spring.io/browse/INT-4001

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM