在 spring-boot 中使用 web-client 解析 text/html 对 xml 的响应

Posted

技术标签:

【中文标题】在 spring-boot 中使用 web-client 解析 text/html 对 xml 的响应【英文标题】:Parse text/html response to xml with web-client in spring-boot 【发布时间】:2021-02-11 16:48:42 【问题描述】:

我正在调用一个 API,它返回内容类型为“text/html”的 xml 响应 当我尝试解析 xml 类中的响应时,我收到了错误消息:

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

API 的实际响应

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

我添加了自定义编解码器来解决这个问题,但不知何故它不起作用。当我添加我得到 json 解码错误时:

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

这是我的代码: API调用

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

网络客户端构建器

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

响应类

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

我认为添加自定义编解码器部分需要修改,但我没有得到确切需要更改的内容。 请让我知道我在哪里做错了。谢谢。

编辑: 我试图像这样修改 XML 的 exchangeStrategies

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

但遇到同样的错误

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

【问题讨论】:

这能回答你的问题吗? Reactive WebClient GET Request with text/html response 我尝试了这篇文章中提到的方法,但没有成功。 然后显示该方法,以及您的错误消息并链接到您尝试过的其他内容,因为没有人想坐在这里告诉您该怎么做,然后您就走了“我试过它没有用“我们想知道什么没用,你的错误信息是什么。不是“它没有用”......那没有帮助。因为我发布的链接就是答案。 @ThomasAndolf 我使用您分享的帖子添加了自定义编解码器。似乎这将适用于 json 响应。当我补充说我得到 json 解码错误:“JSON 解码错误:意外字符(' 您是否考虑过针对您正在调用的 API 报告错误。 【参考方案1】:

Jaxb2XmlDecoder 默认构造函数默认没有“text/html”。您需要将其传递给使用 Jaxb2XmlDecoder(MimeType...supportedMimeTypes) 例如:

clientCodecConfigurer.defaultCodecs().jaxb2Decoder(
Jaxb2XmlDecoder(MimeTypeUtils.APPLICATION_XML, MimeTypeUtils.TEXT_XML, MediaType("application", "*+xml"), MimeTypeUtils.TEXT_HTML))

【讨论】:

以上是关于在 spring-boot 中使用 web-client 解析 text/html 对 xml 的响应的主要内容,如果未能解决你的问题,请参考以下文章

在 spring-boot 中使用 @EnableWebFluxSecurity 时出错

如何在 spring-boot 中禁用 spring-data-mongodb 自动配置

使用spring-boot在Jpa查询中出错

Vaadin 10没有在Spring-Boot中使用模板

如何使用junit在spring-boot中测试常见错误ErrorController

在带有 Spring-boot 的 postgres 中使用整数数组