web-dev-qa-db-fra.com

Analyser json dans Java objets dans spring-mvc

Je sais comment renvoyer json de mon @Controller méthodes utilisant le @ResponseBody annotation.

Maintenant, j'essaie de lire certains arguments json dans mon contrôleur, mais je n'ai pas eu de chance jusqu'à présent. Voici la signature de mon contrôleur:

@RequestMapping(value = "/ajax/search/sync")
public ModelAndView sync(@RequestParam("json") @RequestBody SearchRequest json) {

Mais lorsque j'essaie d'invoquer cette méthode, Spring se plaint que: Failed to convert value of type 'Java.lang.String' to required type 'com.foo.SearchRequest'

Suppression du @RequestBody l'annotation ne semble pas faire de différence.

Analyser manuellement les travaux json, donc Jackson doit être dans le chemin de classe:

// This works
@RequestMapping(value = "/ajax/search/sync")
public ModelAndView sync(@RequestParam("json") String json) {
    SearchRequest request;
    try {
        request = objectMapper.readValue(json, SearchRequest.class);
    } catch (IOException e) {
        throw new IllegalArgumentException("Couldn't parse json into a search request", e);
    }

Des idées? Suis-je en train d'essayer de faire quelque chose qui n'est pas pris en charge?

29
oksayt

Votre paramètre doit être soit un @RequestParam, ou a @RequestBody, pas les deux.

@RequestBody est à utiliser avec POST et requêtes PUT, où le corps de la demande est ce que vous voulez analyser. @RequestParam est pour les paramètres nommés, soit sur l'URL, soit sous forme de soumission de formulaire en plusieurs parties.

Vous devez donc décider lequel vous avez besoin. Voulez-vous vraiment avoir votre JSON comme paramètre de requête? Ce n'est normalement pas comment AJAX fonctionne, il est normalement envoyé en tant que corps de la requête.

Essayez de supprimer le @RequestParam et voyez si cela fonctionne. Sinon, et que vous publiez vraiment le JSON en tant que paramètre de demande, Spring ne vous aidera pas à traiter cela sans plomberie supplémentaire (voir Personnalisation de l'initialisation de WebDataBinder ).

44
skaffman

si vous utilisez jquery du côté client, cela a fonctionné pour moi:

Java:

@RequestMapping(value = "/ajax/search/sync") 
public ModelAndView sync(@RequestBody SearchRequest json) {

Jquery (vous devez inclure json2.js de Douglas Crockford pour avoir la fonction JSON.stringify):

$.ajax({
    type: "post",
    url: "sync", //your valid url
    contentType: "application/json", //this is required for spring 3 - ajax to work (at least for me)
    data: JSON.stringify(jsonobject), //json object or array of json objects
    success: function(result) {
        //do nothing
    },
    error: function(){
        alert('failure');
    }
});
4
rafael lean ansay