Force Spring RestTemplate для использования XmlConverter

Мы интегрируем с третьей стороной, которая отправляет xml с заголовком content-type в виде text/html. Мы планировали использовать Spring RestTemplate для сопоставления его с классами, которые мы создали из xsds, но RestTemplate не может найти подходящий конвертер для использования для контента. Третья сторона отказывается исправить тип контента, поскольку может нарушить интеграцию с другим партнером.

Есть ли способ с Spring RestTemplate заставить его использовать конкретный конвертер? В основном мы делаем следующее:

RestTemplate restTemplate = new RestTemplate();
XmlClass xmlClass = restTemplate.getForObject("http://example.com/", XmlClass.class);

И получите следующее исключение:

org.springframework.web.client.RestClientException: не удалось извлечь ответ: нет подходящего HttpMessageConverter, найденного для типа ответа [XmlClass] и тип содержимого [text/html; charset = ISO-8859-1] в org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:84)

Ответ 1

Реализованное нами решение заключалось в том, чтобы добавить Jaxb2RootElementHttpMessageConverter с MediaType.TEXT_HTML в RestTemplate HttpMessageConverters. Он не идеален, так как он создает избыточный конвертер сообщений jaxb, но он работает.

RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
Jaxb2RootElementHttpMessageConverter jaxbMessageConverter = new Jaxb2RootElementHttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.TEXT_HTML);
jaxbMessageConverter.setSupportedMediaTypes(mediaTypes);
messageConverters.add(jaxbMessageConverter);
restTemplate.setMessageConverters(messageConverters);

Ответ 2

Я не видел примера, опубликованного как это сделать с помощью пользовательского перехватчика, поэтому вот ссылка для ссылки:

public class MyXmlInterceptor implements ClientHttpRequestInterceptor {

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    ClientHttpResponse response = execution.execute(request, body);
    HttpHeaders headers = response.getHeaders();

    // you'd want to check if the value needs to be changed
    if (headers.containsKey("Content-Type")) {
        headers.remove("Content-Type");
    }

    headers.add("Content-Type", "application/xml");

    return response;
}

Затем вам нужно добавить перехватчик к вашему объекту RestTemplate:

RestTemplate t = new RestTemplate();
t.getInterceptors().add(new MyXmlInterceptor());