Заставить Spring RestTemplate использовать XmlConverter

Мы интегрируемся с третьей стороной, которая отправляет xml с заголовком типа содержимого как 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)


person Nathanial    schedule 23.10.2012    source источник


Ответы (3)


Решение, которое мы реализовали, состояло в том, чтобы добавить 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);
person Nathanial    schedule 23.10.2012

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

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());
person Thomas Ehardt    schedule 10.02.2015

Можете ли вы изменить заголовок типа содержимого до того, как произойдет десортировка, добавив собственный перехватчик http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/http/client/ClientHttpRequestInterceptor.html ?

person artbristol    schedule 23.10.2012
comment
Я попытался изменить заголовок accept с помощью перехватчика, чтобы побудить их использовать правильный заголовок, но это не сработало. - person Nathanial; 24.10.2012
comment
Конечно, я бы тоже попробовал. Я имею в виду изменение заголовка response после того, как ответ вернется. - person artbristol; 24.10.2012
comment
Мы решили проблему, добавив в restTemplate дополнительный преобразователь сообщений, который принимает MediaType.TEXT_HTML. Это не идеально, так как создает избыточный преобразователь сообщений jaxb, но он работает - я пытался добавить код в ответ, но он не позволит мне, так как у меня нет представителя. - person Nathanial; 24.10.2012
comment
@Nathanial Звучит как разумное решение. Подождите некоторое время, а затем опубликуйте это как решение. - person artbristol; 24.10.2012