no se encontró ningún convertidor HttpMessageConverter adecuado para el tipo de respuesta


Usando spring, con este código :

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

Consigo

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]

El fragmento a del pojo:

@XmlRootElement(name="TheProductList")
public class ProductList {

@XmlElement(required = true, name = "date")
private LocalDate importDate;
Author: Koray Tugay, 2014-02-18

9 answers

Desde el punto de vista de Spring, ninguna de las instancias HttpMessageConverter registradas con RestTemplate puede convertir el contenido text/html en un objeto ProductList. El método de interés es HttpMessageConverter#canRead(Class, MediaType). La aplicación para todos los resultados anteriores devuelve false, incluido Jaxb2RootElementHttpMessageConverter.

Dado que ningún HttpMessageConverter puede leer su respuesta HTTP, el procesamiento falla con una excepción.

Si puede controlar la respuesta del servidor, modifíquela para establecer el Content-type a application/xml, text/xml, o algo que coincida application/*+xml.

Si no controlas la respuesta del servidor, tendrá que escribir y registrar su propio HttpMessageConverter (que puede extender las clases de Primavera, ver AbstractXmlHttpMessageConverter y sus subclases) que puede leer y convertir text/html.

 24
Author: Sotirios Delimanolis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-18 15:02:32

Si no puede cambiar la respuesta del tipo de medio del servidor, puede extender GsonHttpMessageConverter para procesar tipos de soporte adicionales

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);
    }
}
 7
Author: Vadim Zin4uk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-20 08:57:48

Si está utilizando Spring Boot, es posible que desee asegurarse de que tiene la dependencia de Jackson en su classpath. Puede hacer esto manualmente a través de:

    <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>

O puedes usar el web starter:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 5
Author: Wim Deblauwe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-30 11:19:18

Puede crear una clase, RestTemplateXML, que extiende RestTemplate. Entonces sobreescribe doExecute(URI, HttpMethod, RequestCallback, ResponseExtractor<T>), y explícitamente obtiene response-headers y establece content-type a application/xml.

Ahora Spring lee las cabeceras y sabe que es `application/xml'. Es una especie de truco, pero funciona.

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);
  }
}
 2
Author: Chester Leung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-12 15:16:48

Prueba esto:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.0</version>
</dependency>
 1
Author: Leonardozm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-29 17:42:22

Además de todas las respuestas, si recibe en respuesta text/html mientras esperaba algo más (es decir, application/json), puede sugerir que se produjo un error en el lado del servidor (por ejemplo, 404) y se devolvió la página de error en lugar de sus datos.

Así sucedió en mi caso. Espero que le ahorre tiempo a alguien.

 1
Author: user1913596,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-05 12:35:55

O puede usar

Public void setSupportedMediaTypes (List supportedMediaTypes)

Método que pertenece a AbstractHttpMessageConverter<T>, para agregar algunos ContentTypes que te gustan. De esta manera puede dejar que el MappingJackson2HttpMessageConverter canRead() su respuesta, y transformarlo a su clase deseada,que en este caso, es Clase ProductList.

Y creo que este paso debería conectarse con la inicialización de Contexto Spring. por ejemplo, usando

Implementa ApplicationListener { ... }

 0
Author: avidya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-25 05:47:20

Un refinamiento de La respuesta de Vadim Zin4uk es simplemente usar la clase GsonHttpMessageConverter existente pero invocar el setter setSupportedMediaTypes ().

Para las aplicaciones de spring boot, esto resulta en agregar a lo siguiente a sus clases de configuración:

@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;
}
 0
Author: Guillaume Berche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-22 15:34:42

Esto no responde al problema, pero si alguien llega a esta pregunta cuando se topan con esta excepción de no se encontró un convertidor de mensajes adecuado, aquí está mi problema y solución.

En la primavera 4.0.9, pudimos enviar esto

    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);

En la versión Spring 4.3.5, comenzamos a ver errores con el mensaje de que el convertidor no se encontró. La forma en que funcionan los COnverets es que si lo tienes en tu classpath, se registran.jackson-asl todavía estaba en classpath pero no estaba siendo reconocido por la primavera. Reemplazamos Jackson-asl con faster-xml jackson core. Una vez que agregamos pude ver que el convertidor estaba registrado introduzca la descripción de la imagen aquí

 -1
Author: vsingh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-12 15:46:24