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
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))