2013-04-25 3 views
5

Sto lavorando con Spring e provo a effettuare una chiamata ajax a @ResponseBody nel mio controller.Spring: la chiamata Ajax alla codifica del parametro @ResponseBody non riesce in IE

UPDATE

Va bene, ho aggiunto i cambiamenti mi hanno detto di alle mie impostazioni ajax. Il mio parametro "jtSearchParam" ha ancora lo stesso problema di codifica in IE. + Ho ricevuto un altro errore, 406, l'intestazione della risposta ha il tipo di contenuto sbagliato.

Ecco il mio nuovo codice

Controller:

@RequestMapping(method = RequestMethod.POST, consumes="application/json; charset=utf-8", produces="application/json; charset=utf-8") 
    public @ResponseBody JSONObject getUsers(@RequestParam int jtStartIndex, @RequestParam int jtPageSize, 
      @RequestParam String jtSorting, @RequestParam String jtSearchParam, 
      HttpServletRequest request, HttpServletResponse response) throws JSONException{ 

     Gson gson = new GsonBuilder() 
       .setExclusionStrategies(new UserExclusionStrategy()) 
       .create(); 

     List<User> users = userService.findUsers(jtStartIndex ,jtPageSize, jtSorting, jtSearchParam); 
     Type userListType = new TypeToken<List<User>>() {}.getType(); 

     String usersJsonString = gson.toJson(users, userListType); 
     int totalRecordCount = userDao.getAmountOfRows(jtSearchParam); 

     usersJsonString = "{\"Message\":null,\"Result\":\"OK\",\"Records\":" + usersJsonString + ",\"TotalRecordCount\":" + totalRecordCount + "}"; 

     JSONObject usersJsonObject = new JSONObject(usersJsonString); 

     return usersJsonObject; 
    } 

Quindi, come vedete ho impostato il tipo di contenuto in produces ma che non aiuta. Se metto a punto l'intestazione di risposta che assomiglia a questo: (che provoca un 406 Non accettabile dal browser)

response header

E le mie nuove impostazioni Ajax:

... 
headers: { 
       Accept : "application/json; charset=utf-8", 
       "Content-Type": "application/json; charset=utf-8" 
      }, 
      contentType: "application/json; charset=utf-8", 
      mimeType:"application/json; charset=UTF-8", 
      cache:false, 
      type: 'POST', 
      dataType: 'json' 
... 

E i miei parametri sembra ancora lo stesso in IE!

IE debugged values

+0

la jsp su cui viene eseguito questo codice ha una direttiva che imposta una codifica diversa per la pagina? – Akshay

+1

@AkshaySinghal no è impostato come globale: '<% @ page pageEncoding =" UTF-8 "%>' –

+0

perché stai continuando a mettere il doppio qout su ogni proprietà nell'oggetto json? !! –

risposta

5

Va bene il problema con il tipo di contenuto JSON può essere risolto in questo modo:

Con ResponseEntity siete in grado di cambiare il tipo di contenuto l'intestazione della risposta, in questo modo l'Ajax può interpretare il JSON oggetto la corretta modo e non si ottiene un errore Http 406.

@RequestMapping(method = RequestMethod.POST) 
public ResponseEntity<String> getUsers(@RequestParam int jtStartIndex, @RequestParam int jtPageSize, 
     @RequestParam String jtSorting, @RequestParam String jtSearchParam, 
     HttpServletRequest request, HttpServletResponse response) throws JSONException{ 

    HttpHeaders responseHeaders = new HttpHeaders(); 
    responseHeaders.add("Content-Type", "application/json; charset=utf-8"); 

    Gson gson = new GsonBuilder() 
      .setExclusionStrategies(new UserExclusionStrategy()) 
      .create(); 

    List<User> users = userService.findUsers(jtStartIndex ,jtPageSize, jtSorting, jtSearchParam); 
    Type userListType = new TypeToken<List<User>>() {}.getType(); 

    String usersJsonString = gson.toJson(users, userListType); 
    int totalRecordCount = userDao.getAmountOfRows(jtSearchParam); 

    usersJsonString = "{\"Message\":null,\"Result\":\"OK\",\"Records\":" + usersJsonString + ",\"TotalRecordCount\":" + totalRecordCount + "}"; 

    return new ResponseEntity<String>(usersJsonString, responseHeaders, HttpStatus.OK); 
} 

Il problema con la codifica può essere risolto in questo modo:

IE non codificare il "ü, ä, ecc" correttamente, lo aggiungerà al tuo URL in questo modo: "jtSearchParam = wü" ma dovrebbe in realtà apparire così: "jtSearchParam = w% C3% BC" (Se non lo fai avrai gli errori di codifica su il vostro lato server quando si utilizza IE)

Allora, dove mai si aggiungono alcuni valori al tuo URL, assicurarsi di utilizzare il metodo JavaScript encodeURI su tale valore prima che realmente aggiungerlo al tuo URL Esempio:

encodeURI(jtSearchParam)

+0

Quindi chi aggiunge 'jtSearchParam' anayway? 'jTable' non sembra avere questo parametro :) – zeroflagL

+0

@zeroflagL Sì lo so, l'ho aggiunto io stesso perché voglio cercare nel mio pensiero usertable così :) Se vuoi il codice posso caricarlo. –

3

posso trovare il conflitto nel tipo di contenuto che si sta utilizzando tra il testo e JSON

dataType: 'json' 

contentType: "text/html; charset=utf-8" 

la mia raccomandazione per l'uso JSON per tutte le parti application/json di intestazione e il contenuto tipo anche nel messaggioConverters puoi semplicemente aggiungere i jacks di jackson e convertirà l'oggetto java in json per te, basta cambiare il tipo di ritorno @ResponseBody String a @ResponseBody User mentre User è un bean pojo che contiene getter e setter per i tuoi attributi.

+2

Aggiungerò queste modifiche e vedrò se funziona allora, grazie ancora –

+1

@Bobo Zohdy Mentre la tua raccomandazione è buona, mi chiedo dove vedi il conflitto. – zeroflagL

+0

text/html vs application/json –

2

La codifica del parametro problema

posso immaginare due ragioni per cui questo sta accadendo:

  1. Per qualche motivo il browser pensa la pagina non è codificato in UTF-8
  2. Hai non incluso il CharacterEncodingFilter

Il CharacterEncodingFilter risolve la maggior parte di e problemi di codifica che gli utenti Spring provano. Deve essere il primo filtro nello web.xml.

<filter> 
    <filter-name>encodingfilter</filter-name> 
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
    <init-param> 
     <param-name>encoding</param-name> 
     <param-value>UTF-8</param-value> 
    </init-param> 
    <init-param> 
     <param-name>forceEncoding</param-name> 
     <param-value>true</param-value> 
    </init-param> 

</filter> 

<filter-mapping> 
    <filter-name>encodingfilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

Se si prevede di utilizzare richieste GET e utilizzare Tomcat in modo che l'elemento Connector nella configurazione del server ha la proprietà URIEncoding="utf-8". Altri server possono o non possono aver bisogno di un'impostazione simile.

Il problema JSON ritorno

Questo è facile come aggiungere il Jackson Mapper al classpath e @ResponseBody al tipo di ritorno del metodo. Nel tuo caso suggerisco di creare una classe Message, che assomigli alla tua risposta JSON. Nel caso più semplice il metodo potrebbe essere la seguente:

public @ResponseBody Message getUsers(int jtStartIndex, jtPageSize, String jtSorting, String jtSearchParam) { 

     List<User> users = userService.findUsers(jtStartIndex ,jtPageSize, jtSorting, jtSearchParam); 
     int totalRecordCount = userDao.getAmountOfRows(jtSearchParam); 

     Message message = new Message(); 
     message.setRecords(users); 
     message.setTotalRecordCount(totalRecordCount); 

     return message; 
    } 

ho volutamente omesso @RequestParam perché di solito non è necessario quando i parametri del metodo hanno lo stesso nome dei parametri di richiesta.

Se si utilizza jQuery, non importa che cosa sia l'effettivo content-type della risposta, purché il contenuto possa essere analizzato correttamente come JSON. Utilizzare dataType: 'json', tuttavia, per impedire a jQuery di indovinare.

Il content-type importa, ovviamente, se si utilizza produces. Se non ti serve per restringere i mapping delle richieste, ti consiglio di sbarazzartene.

+1

il filtro di codifica è già presente nel mio web.xml e la chiamata è un POST e in entrambi i casi il mio URIEncoding è impostato su utf-8 comunque. Vedrò sicuramente la tua raccomandazione per la soluzione JSON, grazie ancora –

+0

@JamesCarter Per quello che vale: la tua richiesta è POST ma ciò non significa necessariamente che i parametri non fanno parte dell'URL. Ad ogni modo, ti dispiacerebbe condividere il resto della tua chiamata ajax (cioè il codice JavaScript)? Forse aiuta a trovare la soluzione :) – zeroflagL

+0

È tutto da una libreria chiamata JTable: http://www.jtable.org/ In realtà ho appena modificato le impostazioni. Ma la cosa che mi confonde è che non funziona solo in IE, Firefox funziona come un fascino. IE ha ancora una codifica ASCI come sembra @zeroflagL –

0

Vorrei verificare che chiami il metodo JSON, poiché forse esiste un altro metodo simile che restituisce testo/html.

+2

è sicuramente quel metodo che viene chiamato, l'ho debugato molte volte controllando se poteva essere chiamato un altro, ma non è –