After migrating from Spring Boot 2.7.0 to version > 3 Spring application looses support for accepting application/xml content. It now throws the exception below. I also build new demo apps in Spring boot 3 and the problem remains.
org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/xml' not supported for bodyType=pl.com.company.FunnyDto
at org.springframework.web.reactive.function.BodyExtractors.lambda$readWithMessageReaders$12(BodyExtractors.java:206)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.springframework.web.reactive.function.BodyExtractors.readWithMessageReaders(BodyExtractors.java:202)
at org.springframework.web.reactive.function.BodyExtractors.lambda$toMono$2(BodyExtractors.java:84)
at org.springframework.web.reactive.function.client.DefaultClientResponse.body(DefaultClientResponse.java:134)
at org.springframework.web.reactive.function.client.DefaultClientResponse.bodyToMono(DefaultClientResponse.java:149)
To reproduce this case I have build first app with an endpoint that returns a dto:
@XmlRootElement(name = "transaction")
@XmlAccessorType(XmlAccessType.FIELD)
public class PaymentRegistrationResponseDTO {
@XmlElement(name = "orderID")
private String orderId;
constructors, getters etc...
And the endpoint looks like this
@RestController
public class Controller {
@GetMapping(value = "/xml", produces = MediaType.APPLICATION_XML_VALUE)
public PaymentRegistrationResponseDTO getDTO() {
return new PaymentRegistrationResponseDTO("id");
}
I also added here jackson-dataformat-xml dependency to marshall this dto to xml and send it by Rest:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
On the other side I built second app with a webclient that sends a get request to fetch it:
public PaymentRegistrationResponseDTO getXml() {
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:8090/xml")
.exchangeStrategies(ExchangeStrategies.builder().codecs((configurer) -> {
configurer.defaultCodecs().jaxb2Encoder(new Jaxb2XmlEncoder());
configurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder());
}).build()).build();
return webClient.get()
.accept(MediaType.APPLICATION_XML)
.retrieve()
.bodyToMono(PaymentRegistrationResponseDTO.class)
.block();
}
I also added jakarta bind dependency:
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
Problem 1 - Second app after receveing the xml data can not unmarshal it and I get the exception above.
Problem 2 - First app sends the xml content after adding the jackson-dataformat dependency but it ignores the dto xml annotations and it builds a tag with dto's name instead of the name 'transaction' and inner tag is set to orderID but it sends orderId.
ps. In Spring class WebMvcConfigurationSupport.addDefaultHttpMessageConverters() jackson2XmlPresent is true and Spring context add the MappingJackson2XmlHttpMessageConverter with application/xml support.
I also don't have any javax dependencies in both projects.