web-dev-qa-db-fra.com

Spring MVC - HttpMediaTypeNotAcceptableException

Je continue à avoir cette erreur HttpMediaTypeNotAcceptableException pour les demandes AJAX lors de l'utilisation avec Spring MVC et JSON .. le suivi complet de la pile de l'erreur est .. 

 org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.writeWithMessageConverters(AnnotationMethodHandlerAdapter.Java:1032)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.handleResponseBody(AnnotationMethodHandlerAdapter.Java:972)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.getModelAndView(AnnotationMethodHandlerAdapter.Java:921)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.Java:438)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.Java:424)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:863)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:792)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:851)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:756)
javax.servlet.http.HttpServlet.service(HttpServlet.Java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.Java:717)

la petite recherche que j'ai faite montre que la requête doit contenir quelque chose comme "accept: application/json", ce qui est le cas. voici les en-têtes de requête de firebug ..

Response Headers
Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  2503
Date    Thu, 25 Aug 2011 21:00:05 GMT
Connection  close

Request Headers
Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20 (.NET CLR 3.5.30729)
Accept  application/json, text/javascript, */*; q=0.01
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  115
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/legaldirectory/index.html
Cookie  JSESSIONID=5C97DA19AED4D5FA17F4A58470FAA93B

Maintenant, je suis complètement perdu dans ce qui se passe ici .. quoi d’autre peut se tromper ici pour obtenir cette erreur ...

42
RKodakandla

Assurez-vous d’avoir les éléments suivants dans votre fichier XML Spring:

<context:annotation-config/> 

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
  <list>
    <ref bean="jacksonMessageConverter"/>
  </list>
</property>
</bean>

et tous les articles de votre POJO devraient avoir des getters/setters . J'espère que ça aide

47
danny.lesnik

De: http://georgovassilis.blogspot.ca/2015/10/spring-mvc-rest-controller-says-406.html

Vous avez ceci Spring _ {@RestController et mappé une URL contenant un email dans le chemin de l'URL. Vous avez habilement travaillé sur le problème de la troncature de points [1] et vous êtes prêt à faire le point. Et tout à coup, sur certaines URL, Spring renverra un 406 [2] qui indique que le navigateur a demandé un certain type de contenu et que Spring ne peut pas sérialiser la réponse à ce type de contenu. Le fait est que vous avez fait Spring _ applications pendant des années et que vous avez bien fait toutes les déclarations MVC et que vous avez inclus Jackson et que vous êtes fondamentalement bloqué. Pire encore, cette erreur ne sera générée que sur certains courriels du chemin de l'URL, notamment ceux se terminant par un domaine ".com".

@RequestMapping(value = "/agenda/{email:.+}", method = RequestMethod.GET)
public List<AgendaEntryDTO> checkAgenda(@PathVariable("email") String email)

Le problème [3] est assez délicat: le serveur d’applications négocie le contenu et convainc Spring que le navigateur a demandé un contenu "application/x-msdownload", bien que cela ne se trouve nulle part dans la requête. le navigateur effectivement soumis.

La solution consiste à spécifier un gestionnaire de négociation de contenu pour le contexte de l'application Web:

<mvc:annotation-driven enable-matrix-variables="true"
    content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="defaultContentType" value="application/json" />
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="false" />
    <property name="parameterName" value="mediaType" />
    <property name="ignoreAcceptHeader" value="false" />
    <property name="useJaf" value="false" />
</bean>
21
Alex

Assurez-vous d’ajouter les deux fichiers jar de Jackson au classpath:

  • jackson-core-asl-x.jar
  • jackson-mapper-asl-x.jar

De plus, vous devez avoir les éléments suivants dans votre fichier XML Spring:

<mvc:annotation-driven />
18
jokas

N'oubliez pas que les versions de Spring antérieures à la version 3.1.2 sont compatibles avec JACKSON 1.x et NOT avec JACKSON 2.x. En effet, en passant de JACKSON 1.x à 2.x, les noms de package des classes ont été modifiés. Dans JACKSON 1.x, les classes sont sous org.codehaus.jackson, tandis que dans JACKSON 2.x, elles se trouvent sous com.fasterxml.jackson.

Pour résoudre ce problème, à partir de Spring 3.1.2, ils ont ajouté un nouveau MappingJackson2HttpMessageConverter pour remplacer MappingJacksonHttpMessageConverter.

Vous trouverez plus de détails sur les problèmes de compatibilité dans ce lien: Les annotations de Jackson sont ignorées au printemps

10
Erikson

Parce que c’est le premier hit Google pour "HttpMediaTypeNotAcceptableException", j’aimerais ajouter un autre problème que je suis tombé sur qui a abouti à une exception HttpMediaTypeNotAcceptableException.

Dans mon cas, c’est un contrôleur qui a spécifié "produit", par exemple:

@RequestMapping(path = "/mypath/{filename}", method = RequestMethod.GET,
        produces = { MediaType.APPLICATION_XML_VALUE }

parce que je voulais servir un fichier XML. En même temps, j'utilise une classe avec "@ControllerAdvice" pour intercepter des exceptions, par exemple. si le fichier demandé n'a pas été trouvé. Le gestionnaire d'exception renvoyait JSON afin que l'application client (angulaire) puisse afficher le message d'erreur quelque part dans le SPA.

Le contrôleur souhaitait maintenant renvoyer le code XML, mais le gestionnaire d'exception renvoyant le code JSON, de sorte que l'exception HttpMediaTypeNotAcceptableException était déclenchée. J'ai résolu ce problème en ajoutant JSON car la valeur "produit" possible:

produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}

J'espère que cela aide quelqu'un d'autre. :-)

9
andreas

dans mon cas favorPathExtension (false) m'a aidé

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
    configurer
            .setUseSuffixPatternMatch(false);  // to use special character in path variables, for example, `[email protected]`
}

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer
            .favorPathExtension(false); // to  avoid HttpMediaTypeNotAcceptableException on standalone Tomcat
}

}

5
panser

Dans votre Spring @Configuration class qui étend WebMvcConfigurerAdapter override la méthode configureMessageConverters, par exemple:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

    // http
    HttpMessageConverter converter = new StringHttpMessageConverter();
    converters.add(converter);
    logger.info("HttpMessageConverter added");

    // string
    converter = new FormHttpMessageConverter();
    converters.add(converter);
    logger.info("FormHttpMessageConverter added");

    // json
    converter = new MappingJackson2HttpMessageConverter();
    converters.add(converter);
    logger.info("MappingJackson2HttpMessageConverter added");

}

Et l'erreur aura disparu.

4
zygimantus

J'avais le même problème, mais j'avais compris qu'en fait, ce qui se passe lorsque spring essaie de restituer la réponse, il essaiera de la sérialiser en fonction du type de support que vous avez spécifié et en utilisant les méthodes getter et setter de votre classe 

avant que ma classe ne ressemble à ci-dessous  

public class MyRestResponse{
    private String message;
}

la solution ressemble à celle ci-dessous

public class MyRestResponse{
    private String message;
    public void setMessage(String msg){
        this.message = msg;
    }
    public String getMessage(){
        return this.message;
    }
}

c'est comme ça que ça a fonctionné pour moi

2
mekbib.awoke

Essayez d’ajouter des fichiers "jackson-databind" à pom.xml

`<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.databind-version}</version>
</dependency>`

Et produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE} à @RequestMapping

Es. @RequestMapping(value = "/api/xxx/{akey}/{md5}", produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}@RequestMapping(value = "/api/contrassegno/{akey}/{md5}", produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},...

1
Mauro DiBi

Dans mon cas 

 {"timestamp":1537542856089,"status":406,"error":"Not Acceptable","exception":"org.springframework.web.HttpMediaTypeNotAcceptableException","message":"Could not find acceptable representation","path":"/a/101.xml"}

a été causé par:

path = "/path/{VariableName}" mais je passais VariableName avec un suffixe, comme "abc.xml", ce qui lui permet d'interpréter le fichier .xml comme une sorte de requête au format à la place . Voir les réponses ici.

0
rogerdpack

Comme Alex fait allusion à l'une des réponses, vous pouvez utiliser ContentNegotiationManagerFactoryBean pour définir le type de contenu par défaut sur "application/json", mais j'estimais que cette approche ne me convenait pas.

Ce que j'essayais de faire était de poster un formulaire sur une méthode comme celle-ci.

@RequestMapping(value = "/post/to/me", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public @ResponseBody MyJsonPOJO handlePostForm(@Valid @ModelAttribute("form") ValidateMeForm form, BindingResult bindingResult) throws ApiException {

Ce que j'ai plutôt choisi de faire a été de changer l'en-tête "Accept" de la requête du navigateur en "application/json", ce qui a permis à SpringMVC de trouver ma méthode.

Utilisation de l'API Javascript Fetch (non encore finalisée):

var form = new FormData();
form.append("myData", "data");

let fetchConfig = {
    method: "POST",
    body: form,
    headers: {"Accept": "application/json"}
};

fetch("/post/to/me", fetchConfig)
    .then(... // Javascript Promise API here

Et voilà! Maintenant, SpringMVC trouve la méthode, valide le formulaire et vous permet de renvoyer un POJO JSON.

0
Erik Zivkovic

Dans mon cas, ajoutez simplement l'annotation @ResponseBody pour résoudre ce problème.

0
nguyentaijs

Pour moi, le problème était l'URL à laquelle j'essayais d'accéder. J'ai eu l'URL comme ceci:

{{ip}}:{{port}}/{{path}}/person.html

Lorsque vous terminez url avec .html, cela signifie que vous n’accepterez aucune autre charge utile que le HTML. Pour que mon ordinateur d'extrémité fonctionne correctement, je devais supprimer le fichier .html à la fin. (Vous pouvez également ajouter .json à la fin de l'URL et cela fonctionnera aussi)

De plus, votre modèle d'URL dans web.xml doit être configuré correctement pour vous permettre d'accéder à la ressource. Pour moi c'est

<servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

Auparavant, j'avais *.html* et cela m'empêchait d'accéder au noeud final.

0
Shoter