Affects: Spring Framework (web) < 5.3.1


While improving an existing architectural component (used by many microservices) we have found the need to use jackson-dataformat-xml mappers to cope with legacy XML structures. This has effectively made every spring boot microservice that, in turn, includes this component, to change it's restTemplate default behavior from sending application/JSON requests to sending application/XML requests (and, of course, mapping it's postForObject payloads as XML instead of JSON) and breaking everything.

I've been googling extensively and found several references to simmilar problems: https://stackoverflow.com/questions/57706610/how-to-set-default-messageconverter-to-json-with-jackson-dataformat-xml-added/58376392#58376392 https://stackoverflow.com/questions/47894619/spring-resttemplate-message-converter-priority-when-posting https://stackoverflow.com/questions/57343161/spring-resttemplate-selecting-messageconverter-to-use https://stackoverflow.com/questions/9381665/how-can-we-configure-the-internal-jackson-mapper-when-using-resttemplate

But it seems there is no other way around this behaviour than adding explicit header information to every restTemplate request (wich involves a lot of code changes).

In spring framework 5.3.1 we have seen the spring.xml.ignore property, but this could effectively disable a lot of xml-based functions that may affect other features (logback.xml configuration, maybe?

Nowadays JSON payloads are extremely popular versus XML ones, and developers using restTemplate are often confident that JSON will always be their restTemplate's default format.

I suggest altering the order on which the RestTemplate adds mappers in its default constructor, moving the XML mappers below JSON ones, so JSON keeps on taking precedence even if some third-party library on your microservice depends on the XML mapping libraries, or at least adding a property to influence this behavior (while not altering backwards compatibility) so you can keep on using JSON mappers despite imported libraries.

Comment From: quaff

+1 I've encounter this before.

Comment From: rstoyanchev

Indeed Jackson XML could be ordered after Jackson JSON so that XML is used only where explicitly indicated through the Content-Type header. However, I'm afraid this has been in place for so long that it will cause new regressions in other applications that rely on the present behavior (right or wrong) and we can only make such a behavior change at the point of a major or minor release.

In the mean time you can configure the list converters to use explicitly in the desired order. Given the RestTemplate should be created and configured once, this shouldn't be very onerous.

Comment From: quaff

Indeed Jackson XML could be ordered after Jackson JSON so that XML is used only where explicitly indicated through the Content-Type header. However, I'm afraid this has been in place for so long that it will cause new regressions in other applications that rely on the present behavior (right or wrong) and we can only make such a behavior change at the point of a major or minor release.

In the mean time you can configure the list converters to use explicitly in the desired order. Given the RestTemplate should be created and configured once, this shouldn't be very onerous.

Could you introduce a system property like spring.resttemplate.json.over.xml and default to false.

Comment From: rstoyanchev

Such explicit system properties are not something we do commonly in the Spring Framework. You can however make the Spring configuration conditional on a system property.

Comment From: quaff

Such explicit system properties are not something we do commonly in the Spring Framework. You can however make the Spring configuration conditional on a system property.

FYI: https://github.com/spring-projects/spring-framework/blob/dfb7ca733ad309b35040e0027fb7a2f10f3a196a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java#L75

Comment From: rstoyanchev

I'm not familiar with details of when that property was added but it is very rare. There no examples of the use of a system property that would replace or override what is done in Spring configuration.

Specifically in Spring MVC there isn't any precedent at all except for the more recent "spring.xml.ignore" which does make more sense as a JVM-level property and applies widely to otherwise unrelated parts of the framework. If we add this here, we would have to be open to doing it for just about anything.

Comment From: mediocaballero

Thanks for all the feedback, and sorry for not getting back sooner. I understand your point.

@rstoyanchev

In the mean time you can configure the list converters to use explicitly in the desired order. Given the RestTemplate should be created and configured once, this shouldn't be very onerous.

Sure, and that's the way we are currently dealing with it. It's just a bit weird where you can get into a situation that, by including a (supposedly) independent library for something that has nothing to do with REST calls in your app, if that library has a transitive dependency on jackson-dataformat-xml then the default behaviour of every RestTemplate call in the original app will suddenly get changed from JSON to XML and you will need code changes in your app (not just configuration or dependencies) to solve that.

In an enterprise environment, where 'the app' belongs to a team and 'the library' belongs to another this becomes quite a big headache and a conflict of interests ;-)