0

I'm calling an API which returns xml response with content-type "text/html" When I try to parse the response in xml class, I'm getting the error message:

Content type 'text/html' not supported for bodyType=Response

Actual response of API

<?xml version='1.0' encoding='UTF-8'?>
<response version="1.0">
    <responseCode>200</responseCode>
    <responseMsg>some message</responseMsg>
</response>

I added custom codec to solve this but somehow it doesn't work. when I added that I got json decoding error:

JSON decoding error: Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')

Here is my code: API calling

return webClient.get()
            .uri { builder ->
                builder.path("/apiPath")
                    .queryParams(queryParams)
                    .build()
            }
            .retrieve()
            .onStatus({ it != HttpStatus.OK }) {
                RuntimeException("").toMono()
            }
            .bodyToMono(Response::class.java)
            .doOnError {
                logger.error { "Error" }
            }.block()

web client builder

    @Bean
    fun webClient(): WebClient = WebClient.builder()
        .exchangeStrategies(ExchangeStrategies.builder().codecs(this::acceptedCodecs).build())
        .baseUrl("apiUrl")
        .build()

    private fun acceptedCodecs(clientCodecConfigurer: ClientCodecConfigurer) {
        clientCodecConfigurer.customCodecs().register(Jackson2JsonEncoder(ObjectMapper(), TEXT_HTML))
        clientCodecConfigurer.customCodecs().register(Jackson2JsonEncoder(ObjectMapper(), TEXT_HTML))
    }

Response class

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "response")
data class Response(
    @XmlElement
    val responseCode: String = "2000",
    @XmlElement
    val responseMsg: String = "OK",
)

I believe adding custom codec part needs to be modified but I'm not getting what exactly have to change. Please let me know where I'm doing wrong. Thank you.

Edit: I tried to modify exchangeStrategies for XML like this

clientCodecConfigurer.defaultCodecs().jaxb2Decoder(Jaxb2XmlDecoder())
clientCodecConfigurer.defaultCodecs().jaxb2Encoder(Jaxb2XmlEncoder())

but got the same error

message : Content type 'text/html' not supported for bodyType=Response
Avv
  • 555
  • 1
  • 10
  • 18
  • Does this answer your question? [Reactive WebClient GET Request with text/html response](https://stackoverflow.com/questions/48553242/reactive-webclient-get-request-with-text-html-response) – Toerktumlare Oct 29 '20 at 10:29
  • I tried the approach mentioned in this post but no luck. – Avv Oct 29 '20 at 10:48
  • then show the approach, and your error msg and link to other things you have tried, because no one wants to sit here and tell you what to do and you go "i have tried that it didnt work" we want to know WHAT didnt work, whats your error msg. Not "it didnt work"... thats NO help. Because the link i posted IS the answer. – Toerktumlare Oct 29 '20 at 10:50
  • @ThomasAndolf I added custom codec using the post you shared. seems like that will work for json response. when I added that I got json decoding error : "JSON decoding error: Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null');" I'm getting the xml response. And I tried this one thing that I've already mentioned in this post. – Avv Oct 29 '20 at 11:03
  • 1
    Have you considered reporting a bug against the API you're calling. – Mark Rotteveel Oct 29 '20 at 11:35

1 Answers1

1

Jaxb2XmlDecoder default constructor doesn't have "text/html" by default. You need to pass it to using Jaxb2XmlDecoder(MimeType... supportedMimeTypes) For example:

clientCodecConfigurer.defaultCodecs().jaxb2Decoder(
Jaxb2XmlDecoder(MimeTypeUtils.APPLICATION_XML, MimeTypeUtils.TEXT_XML, MediaType("application", "*+xml"), MimeTypeUtils.TEXT_HTML))
Dipti
  • 106
  • 1
  • 8