Stato HTTP 406. Spring MVC 4.0, jQuery, JSON

Voglio inviare JSON dal mio controller. Ho la seguente configurazione.

spring-servlet.xml:

           

.js:

 function testAjax() { var data = {userName: "MyUsername", password:"Password"}; $.ajax({ url: 'ajax/test.htm', dataType : 'json', type : 'POST', contentType: "application/json", data: JSON.stringify(data), success: function(response){ alert('Load was performsd.'); } }); } 

UserTest.java:

 public class UserTest { private String userName; private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } 

TestAjaxController.java:

 @Controller @RequestMapping("/ajax") public class TestAjaxController { @RequestMapping(method = RequestMethod.POST, value = "/test.htm") public @ResponseBody UserTest testAjaxRequest(@RequestBody UserTest user) { return user; } } 

pom.xml:

   org.codehaus.jackson jackson-mapper-asl 1.9.13   org.codehaus.jackson jackson-core-asl 1.9.13  

Quando faccio questa richiesta, ottengo il mio Controller JSON rappresentato come object UserTest. Ma al ritorno:

Stato HTTP 406 – La risorsa identificata da questa richiesta è solo in grado di generare risposte con caratteristiche non accettabili in base alla richiesta “accetta” intestazioni.

Cosa sto facendo di sbagliato? Lo so, c’è un sacco di domande su questi casi, ma non riesco a risolverlo per 2 giorni …

AGGIORNAMENTO Ho trovato la soluzione !! È solo necessario restituire un object. Non un object Utente o qualcosa del genere. Ma return Object;

  public @ResponseBody Object testAjaxRequest(@RequestBody UserTest user) { List list = new ArrayList(); list.add(user); list.add(user); list.add(user); return list; 

Il problema principale qui è che il percorso "/test.htm" utilizzerà la negoziazione del contenuto prima di controllare il valore di un’intestazione Accept . Con un’estensione come *.htm , Spring utilizzerà un org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy e risolverà che il tipo di supporto accettabile da restituire è text/html che non corrisponde a quello prodotto da MappingJacksonHttpMessageConverter , ad es. application/json e quindi viene restituito un 406.

La soluzione semplice consiste nel cambiare il percorso in qualcosa di simile a /test , in cui la negoziazione del contenuto basata sul percorso non risolverà alcun tipo di contenuto per la risposta. Invece, una diversa ContentNegotiationStrategy basata sulle intestazioni risolverà il valore dell’intestazione Accept .

La soluzione complicata consiste nel modificare l’ordine degli oggetti ContentNegotiationStrategy registrati con RequestResponseBodyMethodProcessor che gestisce il tuo @ResponseBody .

Ho avuto lo stesso problema alla fine era la versione di org.codehaus.jackson 1.9.x, quando sono passato da 1.9.x jackson a 2.x (fasterxml) nel mio pom.xml

  com.fasterxml.jackson.core jackson-core 2.2.3   com.fasterxml.jackson.core jackson-databind 2.2.3   com.fasterxml.jackson.core jackson-annotations 2.2.3  

inoltre è necessario:

Mi sono imbattuto in questo problema durante l’aggiornamento di Spring in un progetto legacy. Il suffisso .html degli endpoint AJAX (che cercavano di restituire JSON) sono stati effettivamente forzati per provare a produrre HTML a causa del suffisso e, poiché i gestori restituivano un object, la richiesta terminava con un errore 406 poiché Spring non poteva t capire come rendere HTML da un object Java semplice.

Invece di alterare i suffissi endpoint o eseguire una configurazione completa di una ContentNegotiationStrategy personalizzata, questa modifica era sufficiente:

  

cambiato in:

     

L’aggiunta di queste righe alla configurazione del contesto ha risolto lo stesso problema per me:

       

Ho usato Spring 4.1.x e Jackson 2.4.2

Assicurati di usare produce = “application / json” nelle tue annotazioni.