添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
冷冷的电影票  ·  Caused by: ...·  1 年前    · 
威武的小蝌蚪  ·  In XML Configuration ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Using spring, with this code :

List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
for(HttpMessageConverter httpMessageConverter : messageConverters){
  System.out.println(httpMessageConverter);
ResponseEntity<ProductList> productList = restTemplate.getForEntity(productDataUrl,ProductList.class);

I get

org.springframework.http.converter.ByteArrayHttpMessageConverter@34649ee4
org.springframework.http.converter.StringHttpMessageConverter@39fba59b
org.springframework.http.converter.ResourceHttpMessageConverter@383580da
org.springframework.http.converter.xml.SourceHttpMessageConverter@409e850a
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@673074aa
org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@1e3b79d3
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@52bb1b26
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.mycopmany.ProductList] and content type [text/html;charset=UTF-8]

The a snippet of the pojo :

@XmlRootElement(name="TheProductList")
public class ProductList {
@XmlElement(required = true, name = "date")
private LocalDate importDate;
                The media type coming back is text/html and not application/xml.  Have you looked at the response to see if you are getting and HTML page for an error message rather than the real XML response you are looking for?
– bdoughan
                Feb 18, 2014 at 13:52
                so I am downloading the response to a file, converting to a streamsource, and using the unmarshaller that way.
– NimChimpsky
                Feb 18, 2014 at 14:39
                For consuming text/html respone in spring rest template, look at this answer and upvote if it works for you! stackoverflow.com/a/76557476/2181576
– veritas
                Jun 26 at 14:13

From a Spring point of view, none of the HttpMessageConverter instances registered with the RestTemplate can convert text/html content to a ProductList object. The method of interest is HttpMessageConverter#canRead(Class, MediaType). The implementation for all of the above returns false, including Jaxb2RootElementHttpMessageConverter.

Since no HttpMessageConverter can read your HTTP response, processing fails with an exception.

If you can control the server response, modify it to set the Content-type to application/xml, text/xml, or something matching application/*+xml.

If you don't control the server response, you'll need to write and register your own HttpMessageConverter (which can extend the Spring classes, see AbstractXmlHttpMessageConverter and its sub classes) that can read and convert text/html.

@Bean
public RestTemplate restTemplate() {
   final RestTemplate restTemplate = new RestTemplate();
   List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
   MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
   converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
   messageConverters.add(converter);
   restTemplate.setMessageConverters(messageConverters);
   return restTemplate;
                Not working for response File and type application/actet-stream for me: HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of java.io.File out of START_ARRAY token
– Hollerweger
                Oct 21, 2020 at 15:25

If you are using Spring Boot, you might want to make sure you have the Jackson dependency in your classpath. You can do this manually via:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

Or you can use the web starter:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

In addition to all the answers, if you happen to receive in response text/html while you've expected something else (i.e. application/json), it may suggest that an error occurred on the server side (say 404) and the error page was returned instead of your data.

So it happened in my case. Hope it will save somebody's time.

Change your ResponseEntity type to String. Print out the response. Will help you debug easily !! Eg: ResponseEntity<String> responseEntity= restTemplate.exchange(uri, HttpMethod.POST, requestEntity, String.class); – wardaddy Jun 15, 2022 at 3:58

If you can't change server media-type response, you can extend GsonHttpMessageConverter to process additional support types

public class MyGsonHttpMessageConverter extends GsonHttpMessageConverter {
    public MyGsonHttpMessageConverter() {
        List<MediaType> types = Arrays.asList(
                new MediaType("text", "html", DEFAULT_CHARSET),
                new MediaType("application", "json", DEFAULT_CHARSET),
                new MediaType("application", "*+json", DEFAULT_CHARSET)
        super.setSupportedMediaTypes(types);
                A refinement is just to use the existing GsonHttpMessageConverter class but invoke the setSupportedMediaTypes() setter.
– Guillaume Berche
                Feb 22, 2018 at 15:29

You can make up a class, RestTemplateXML, which extends RestTemplate. Then override doExecute(URI, HttpMethod, RequestCallback, ResponseExtractor<T>), and explicitly get response-headers and set content-type to application/xml.

Now Spring reads the headers and knows that it is `application/xml'. It is kind of a hack but it works.

public class RestTemplateXML extends RestTemplate {
  @Override
  protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
        ResponseExtractor<T> responseExtractor) throws RestClientException {
     logger.info( RestTemplateXML.class.getSuperclass().getSimpleName() + ".doExecute() is overridden");
     Assert.notNull(url, "'url' must not be null");
     Assert.notNull(method, "'method' must not be null");
     ClientHttpResponse response = null;
     try {
        ClientHttpRequest request = createRequest(url, method);
        if (requestCallback != null) {
           requestCallback.doWithRequest(request);
        response = request.execute();
        // Set ContentType to XML
        response.getHeaders().setContentType(MediaType.APPLICATION_XML);
        if (!getErrorHandler().hasError(response)) {
           logResponseStatus(method, url, response);
        else {
           handleResponseError(method, url, response);
        if (responseExtractor != null) {
           return responseExtractor.extractData(response);
        else {
           return null;
     catch (IOException ex) {
        throw new ResourceAccessException("I/O error on " + method.name() +
              " request for \"" + url + "\":" + ex.getMessage(), ex);
     finally {
        if (response != null) {
           response.close();
  private void logResponseStatus(HttpMethod method, URI url, ClientHttpResponse response) {
     if (logger.isDebugEnabled()) {
        try {
           logger.debug(method.name() + " request for \"" + url + "\" resulted in " +
                 response.getRawStatusCode() + " (" + response.getStatusText() + ")");
        catch (IOException e) {
           // ignore
  private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException {
     if (logger.isWarnEnabled()) {
        try {
           logger.warn(method.name() + " request for \"" + url + "\" resulted in " +
                 response.getRawStatusCode() + " (" + response.getStatusText() + "); invoking error handler");
        catch (IOException e) {
           // ignore
     getErrorHandler().handleError(response);
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.1</version>
</dependency>
                Welcome to Stack Overflow! While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
– Scott Weldon
                Jul 29, 2016 at 17:21

method which belongs to AbstractHttpMessageConverter<T>, to add some ContentTypes you like. This way can let the MappingJackson2HttpMessageConverter canRead() your response, and transform it to your desired Class, which on this case,is ProductList Class.

and I think this step should hooked up with the Spring Context initializing. for example, by using

implements ApplicationListener {

A refinement of Vadim Zin4uk's answer is just to use the existing GsonHttpMessageConverter class but invoke the setSupportedMediaTypes() setter.

For spring boot apps, this results into adding to following to your configuration classes:

@Bean
public GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) {
    GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
    converter.setGson(gson);
    List<MediaType> supportedMediaTypes = converter.getSupportedMediaTypes();
    if (! supportedMediaTypes.contains(TEXT_PLAIN)) {
        supportedMediaTypes = new ArrayList<>(supportedMediaTypes);
        supportedMediaTypes.add(TEXT_PLAIN);
        converter.setSupportedMediaTypes(supportedMediaTypes);
    return converter;

This is not answering the problem but if anyone comes to this question when they stumble upon this exception of no suitable message converter found, here is my problem and solution.

In Spring 4.0.9, we were able to send this

    JSONObject jsonCredential = new JSONObject();
    jsonCredential.put(APPLICATION_CREDENTIALS, data);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> res = restTemplate.exchange(myRestUrl), HttpMethod.POST,request, String.class);

In Spring 4.3.5 release, we starting seeing errors with the message that converter was not found.

The way Convertors work is that if you have it in your classpath, they get registered.

Jackson-asl was still in classpath but was not being recognized by spring. We replaced Jackson-asl with faster-xml jackson core.

Once we added I could see the converter being registered.

I also had the same error message : "Could not extract response: no suitable HttpMessageConverter found for response type ..."

This occured when I was trying to get info from a link that did not return the object type I wanted to convert or when the link did not return anything. I handled it using a try catch block :

 try {
        status = restTemplate
            .getForObject(statusResourceUrl, Status.class);
        //TODO add new exceptions if necessary or simply use Exception
    } catch (BeanCreationException | UnknownContentTypeException | HttpClientErrorException e) {
        status.setStatus("DOWN");
        System.out.println("exception " + e.getMessage());

I was also facing the same issue in last week. Tried the above solution which marked as accepted but didnt worked.

When this will come : While calling the external URL(REST call) and the response is the complex object.

What was wrong : was adding unnecessary the converter using the below code

org.springframework.web.client.restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));

Solution: Just add the below dependency

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

Because spring boot add all the default message converters. No need to add any extra. Not even any JaxB dependency. If present please delete and Try it will work

Danke!!

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.