使用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
相关产品推荐
相关产品推荐

