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

使用Spring Boot TestRestTemplate相对路径引发JSON转换异常的解决方法

解决TestRestTemplate相对路径下XML解析异常的问题

这个问题我之前碰到过,本质是TestRestTemplate在使用相对路径时,请求头或消息转换器的优先级问题,导致XML响应被错误地当作JSON来解析。我们来拆解原因并给出解决方案:

问题根源

当你使用完整URL请求时,服务端可能已经正确识别请求上下文,返回了application/xml类型的响应,TestRestTemplate也能匹配到对应的XML转换器完成解析;但切换到相对路径后,默认的请求头Accept是*/*,服务端可能优先返回JSON,或者客户端的消息转换器列表里JSON转换器优先级更高——它会尝试去解析XML格式的内容,而XML的根节点在JSON转换器看来是一个对象,和你期望的数组类型不匹配,自然就抛出了反序列化异常。

可行解决方案

方案1:显式设置Accept请求头为XML

直接告诉服务端你期望XML格式的响应,这样服务端会返回XML,客户端也会用对应的转换器处理:

// 构建请求头,指定Accept为application/xml
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
HttpEntity<Void> requestEntity = new HttpEntity<>(headers);

// 携带请求头发起请求
ResponseEntity<List<City>> cities = restTemplate.exchange(
    appPath, 
    HttpMethod.GET, 
    requestEntity, 
    paramType
);

方案2:调整TestRestTemplate的消息转换器优先级

把XML转换器移到消息转换器列表的最前面,确保客户端优先用它解析响应:

@Autowired
private TestRestTemplate restTemplate;

@Before
public void configureRestTemplate() {
    List<HttpMessageConverter<?>> converters = restTemplate.getRestTemplate().getMessageConverters();
    
    // 找到XML转换器并移到首位
    for (int i = 0; i < converters.size(); i++) {
        if (converters.get(i) instanceof MappingJackson2XmlHttpMessageConverter) {
            MappingJackson2XmlHttpMessageConverter xmlConverter = 
                (MappingJackson2XmlHttpMessageConverter) converters.remove(i);
            converters.add(0, xmlConverter);
            break;
        }
    }
}

方案3:在exchange方法中指定响应MediaType

使用exchange的重载方法,直接指定响应的媒体类型,强制TestRestTemplate用XML转换器解析:

ResponseEntity<List<City>> cities = restTemplate.exchange(
    appPath, 
    HttpMethod.GET, 
    null, 
    paramType, 
    MediaType.APPLICATION_XML
);

这三个方案都能解决你的问题,其中方案1最直接,明确约定了请求的响应类型,推荐优先尝试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:32:49