Spring Boot 3 support for application/xml content in http calls

641 Views Asked by At

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.

0

There are 0 best solutions below