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

RestTemplate未返回完整XML响应问题排查求助

问题:Spring Boot RestTemplate调用XML接口缺失<revenueAccessorialList>元素

用Spring Boot调用返回XML格式的REST服务时,Postman能拿到完整的XML响应,但用RestTemplate的exchange或postForEntity方法调用时,<revenueAccessorialList>元素(包括第一个有效项和两个标记为xsi:nil="true"的空元素)全部缺失。求解决办法,以及除了RestTemplate之外的替代方案。

示例XML响应

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RateResponse>
    <RateQueryResponses>
        <rateQueryResponseList>
            <carrierCode>CUST</carrierCode>
            <mode>SLTL</mode>
            < ... more content here .... >
            <declaredValue>0.0</declaredValue>
            <routingGuideLane>
                <destLocType></destLocType>
                <frequency></frequency>
                <laneDest></laneDest>
                <origLocType></origLocType>
            </routingGuideLane>
            <routingGuideLaneCarrierDetails>
                <capacityVolume>0</capacityVolume>
                <carrierCode>CUST</carrierCode>
                <rank></rank>
                <tier></tier>
            </routingGuideLaneCarrierDetails>
            <totalRevenue>
                <rate>0.0</rate>
                <revenueAccessorialList>
                    <accessorialCode>FUEL</accessorialCode>
                    <accessorialRevenue>0.0</accessorialRevenue>
                    <approved>true</approved>
                    <calculationMethod>PCT</calculationMethod>
                    <minimumRate>0.0</minimumRate>
                    <payeeCarrierId>-2147483648</payeeCarrierId>
                    <rate>0.735</rate>
                </revenueAccessorialList>
                <revenueAccessorialList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <revenueAccessorialList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <stopOffRevenue>0.0</stopOffRevenue>
                <totalAccessorialRevenue>0.0</totalAccessorialRevenue>
            </totalRevenue>
        </rateQueryResponseList>
    </RateQueryResponses>
</RateResponse>

当前使用的代码

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_XML);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));

HttpEntity<QueryRequest> requestlEntity = new HttpEntity<>(rreq, headers);
ResponseEntity<String> qrlEntity = null;
return restTemplate.exchange(serviceEp, HttpMethod.POST, requestlEntity, String.class);
//  return restTemplate.postForEntity(serviceEp, requestlEntity, String.class);

解决办法

一、修复RestTemplate的问题

1. 自定义XML消息转换器

RestTemplate默认的MappingJackson2XmlHttpMessageConverter可能对重复元素和xsi:nil属性处理不当,可通过配置Jackson XML模块调整:

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    MappingJackson2XmlHttpMessageConverter converter = new MappingJackson2XmlHttpMessageConverter();
    JacksonXmlModule module = new JacksonXmlModule();
    
    // 关闭默认包装,适配重复元素
    module.setDefaultUseWrapper(false);
    XmlMapper xmlMapper = new XmlMapper(module);
    
    // 忽略未知属性,避免解析报错
    xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // 允许接受空数组/元素,保留xsi:nil的项
    xmlMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, false);
    
    converter.setObjectMapper(xmlMapper);
    // 替换原有的XML转换器
    restTemplate.getMessageConverters().replaceAll(c -> 
        c instanceof MappingJackson2XmlHttpMessageConverter ? converter : c
    );
    return restTemplate;
}

2. 直接读取原始响应流

如果只需要原始XML字符串,绕过消息转换器的自动处理,直接读取响应体的输入流:

ResponseEntity<Resource> response = restTemplate.exchange(serviceEp, HttpMethod.POST, requestlEntity, Resource.class);
String rawXml = StreamUtils.copyToString(response.getBody().getInputStream(), StandardCharsets.UTF_8);
// 后续处理rawXml即可

二、替代RestTemplate的方案

1. WebClient(Spring官方推荐)

Spring WebFlux提供的WebClient是异步非阻塞的HTTP客户端,处理XML更灵活:

// 配置WebClient
@Bean
public WebClient webClient() {
    return WebClient.builder()
            .codecs(configurer -> {
                // 使用JAXB编解码器处理XML
                configurer.defaultCodecs().jaxb2Encoder(new Jaxb2Encoder());
                configurer.defaultCodecs().jaxb2Decoder(new Jaxb2Decoder());
            })
            .build();
}

// 调用示例(同步方式)
String xmlResponse = webClient.post()
        .uri(serviceEp)
        .contentType(MediaType.APPLICATION_XML)
        .accept(MediaType.APPLICATION_XML)
        .bodyValue(rreq)
        .retrieve()
        .bodyToMono(String.class)
        .block();

2. Apache HttpClient

直接使用原生HTTP客户端,完全控制请求和响应处理,避免Spring消息转换器的干扰:

// 需要先把QueryRequest序列化为XML字符串,这里假设已经有xmlRequestString
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(serviceEp);

httpPost.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
httpPost.setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE);
httpPost.setEntity(new StringEntity(xmlRequestString, StandardCharsets.UTF_8));

CloseableHttpResponse response = httpClient.execute(httpPost);
String rawXml = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);

// 关闭资源
response.close();
httpClient.close();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:51:00