You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3中WebClient处理application/xml遇类型不支持异常

Spring Boot 3.x WebClient处理application/xml报UnsupportedMediaTypeException问题解决

问题背景

从Spring Boot 2.7.2升级到3.x版本后,通过@Configuration配置的WebClient调用XML接口时抛出UnsupportedMediaTypeException,提示Content type 'application/xml' not supported for bodyType=com.package.ResponseObject。已引入以下JAXB依赖:

  • jaxb-core - 2.2.11
  • jaxb-impl - 2.2.11
  • jaxb-runtime - 2.3.6
  • jaxb-api - 2.3.1

WebClient配置代码:

public WebClient getWebClient(String url) {

    WebClient webClient = null;
    try {
        webClient = WebClient.builder().baseUrl(url)
                .defaultHeaders(headers -> {
                    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
                    headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE);
                    headers.setBasicAuth(username, password);
                })
                .exchangeStrategies(
                    ExchangeStrategies.builder()
                    .codecs( configurer -> 
                        configurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder())
                    )
                    .build()
                )
                .build();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return webClient;
}

调用代码:

public ResponseObject getResponse(RequestObject request, String clientUrl) throws Exception {
    ResponseObject result = null;
    try {
        WebClient client = getWebClient(clientUrl);
        
        BodyInserter<RequestObject, ReactiveHttpOutputMessage> inserter = BodyInserters.fromValue(request);
        
        result = client.post().body(inserter).retrieve().bodyToMono(ResponseObject.class).block();
        
    } catch (Exception ex) {
        throw ex;
    }
    return result;
}

错误日志:

2023-06-18 17:09:54.875| WARN|r.n.h.c.HttpClientConnect|[d243e7af-1, L:/R:xx.xx.xx.com] The connection observed an error

org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/xml' not supported for bodyType=com.package.ResponseObject
    at org.springframework.web.reactive.function.BodyInserters.unsupportedError(BodyInserters.java:392) ~[spring-webflux-6.0.9.jar:6.0.9]
    at org.springframework.web.reactive.function.BodyInserters.writeWithMessageWriters(BodyInserters.java:382) ~[spring-webflux-6.0.9.jar:6.0.9]
    at org.springframework.web.reactive.function.BodyInserters.lambda$fromValue$1(BodyInserters.java:98) ~[spring-webflux-6.0.9.jar:6.0.9]
    at org.springframework.web.reactive.function.client.DefaultClientRequestBuilder$BodyInserterRequest.writeTo(DefaultClientRequestBuilder.java:272) ~[spring-webflux-6.0.9.jar:6.0.9]

原因分析

  1. 依赖不兼容:Spring Boot 3.x基于Jakarta EE 9+,所有javax.*包已替换为jakarta.*,当前引入的是旧的javax版本JAXB依赖,无法与Spring Boot 3的Jakarta生态兼容。
  2. 缺少XML编码器配置:当前WebClient仅配置了Jaxb2XmlDecoder(用于解析响应XML),但请求时需要Jaxb2XmlEncoder来序列化请求体为XML,未配置编码器导致请求阶段无法处理application/xml类型。

解决方案

1. 替换为Jakarta版本的JAXB依赖

移除所有旧的javax JAXB依赖,添加Jakarta版本的依赖(以Maven为例):

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <scope>runtime</scope>
</dependency>

注:Spring Boot 3.x的bom会管理这些依赖的版本,无需手动指定版本号。

2. 同时配置Jaxb2XmlDecoder和Jaxb2XmlEncoder

修改WebClient配置,在ExchangeStrategies中同时添加编码器和解码器:

public WebClient getWebClient(String url) {
    try {
        return WebClient.builder().baseUrl(url)
                .defaultHeaders(headers -> {
                    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
                    headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE);
                    headers.setBasicAuth(username, password);
                })
                .exchangeStrategies(ExchangeStrategies.builder()
                        .codecs(configurer -> {
                            DefaultCodecs defaultCodecs = configurer.defaultCodecs();
                            defaultCodecs.jaxb2Decoder(new Jaxb2XmlDecoder());
                            defaultCodecs.jaxb2Encoder(new Jaxb2XmlEncoder());
                        })
                        .build())
                .build();
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

3. 更新实体类的JAXB注解

将实体类(RequestObject、ResponseObject)中原来的javax.xml.bind.*注解替换为jakarta.xml.bind.*,例如:

  • 替换@javax.xml.bind.annotation.XmlRootElement为@jakarta.xml.bind.annotation.XmlRootElement
  • 替换@javax.xml.bind.annotation.XmlElement为@jakarta.xml.bind.annotation.XmlElement
  • 其他JAXB注解同理更新

验证

修改完成后重新启动服务,调用接口即可正常处理application/xml类型的请求和响应。

内容的提问来源于stack exchange,提问作者user3312160

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:44:56