Reputation: 81
Another question for the same project once mentioned in this question. We have now developed quite a few routes to serve a REST/JSON web service from a composite back-end.
The endpoint is an <int-http:inbound-gateway> that performs implicit JSON to object from the request and object to JSON for the response. Now we really need to tune Jackson to solve a few issues with the JSON we deliver in the responses. Nothing fancy or unusual: mostly, serve dates as String instead of Timestamps, removing null attributes, registering the JSR-310 module.
For the other modules in the platform, we use Java DSL with a @Configuration class and a bean like this:
@Configuration
public class ControllerConfig {
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setSerializationInclusion(Include.NON_NULL);
return objectMapper;
}
}
But it seems to have no effect on Spring Integration. I have also tried Spring Boot configuration:
spring.jackson.default-property-inclusion=NON_NULL
and it does not work either. I read very carefully this thread and my understanding from Artem Bilan's answer is that indeed, Spring Integration does not consider the Spring Boot configuration.
So... I'm feeling stupid: what is the canonical way of configuring Jackson globally for Spring Integration ?
jackson 2.8.7 / spring 4.3.7 / spring boot 1.5.2 / spring integration 4.3.8
Upvotes: 2
Views: 1550
Reputation: 81
A big thank you to @Artem Bilan for answering my question promptly and showing me the way to go (after I fought for two days on my own).
Customizing the HttpMessageConverter is indeed the good direction. The code below is not the finest I've written but it does the job nicely. I have added this stanza to our @Configuration bean:
@Bean
public List<HttpMessageConverter<?>> customMessageConverters() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setSerializationInclusion(Include.NON_NULL);
jsonConverter.setObjectMapper(objectMapper);
List<HttpMessageConverter<?>> result = new ArrayList<HttpMessageConverter<?>>();
result.add(jsonConverter);
return result;
}
Then, the magic suggested by Artem Bilan works nicely: we have just added
message-converters="customMessageConverters"
to our inbound-gateway.
I hope this helps someone, someday. My apologies for any typo but all this is coded in a bank where posting to StackOverflow is blocked, hence no copy and paste...
Upvotes: 1
Reputation: 121550
Correct. Spring Integration is a pure Spring Framework extension and it indeed knows nothing about conventional auto-configuration and injections.
So, what you have to do is don not forget to inject your objectMapper
whenever it is necessary.
For example for that <int-http:inbound-gateway>
you have to inject a proper set of the HttpMessageConverter
. For example I see that Spring Boot provides the HttpMessageConverters
bean. I believe that MappingJackson2HttpMessageConverter
is injected to that one by the JacksonHttpMessageConvertersConfiguration
. So, you can use it for your purpose like this:
<int-http:inbound-gateway
message-converters="#{messageConverters.converters}">
Upvotes: 1