web-dev-qa-db-fra.com

Spring 3.0 produisant une réponse JSON à l'aide du convertisseur de messages de Jackson

je configure mon messageconverter comme alors de Jackson

class Foo{int x; int y}

et dans le contrôleur

@ResponseBody
public Foo method(){
   return new Foo(3,4)
}

à partir de là, je compte renvoyer une chaîne JSON {x: '3', y: '4'} à partir du serveur sans autre configuration. mais obtenir une réponse d'erreur 404 à ma demande ajax 

Si la méthode est annotée avec @ResponseBody, le type de retour est écrit dans le corps HTTP de la réponse. La valeur de retour sera convertie en type d'argument de méthode déclaré à l'aide de HttpMessageConverters.

Ai-je tort ? ou devrais-je convertir moi-même l'objet de réponse en chaîne Json moi-même à l'aide d'un sérialiseur, puis en renvoyant cette chaîne en tant que réponse (je pourrais faire les réponses correctement) ou dois-je effectuer d'autres configurations? comme ajouter des annotations pour la classe Foo 

voici mon conf.xml 

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">

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

23
dupdup

Vous avez besoin des éléments suivants:

  1. Définition du modèle de programmation basé sur les annotations: mettez <mvc:annotation-driven /> dans spring.xml
  2. Placez jaskson jar (Maven artifactId est org.codehaus.jackson:jackson-mapper-asl) dans classpath.
  3. Utilisez comme suit:

    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
    public @ResponseBody Foo method(@Valid Request request, BindingResult result){
    return new Foo(3,4)
    }
    

Cela fonctionne pour moi.

S'il vous plaît noter que 

  1. @ResponseBody est appliqué pour renvoyer le type, pas pour la définition de la méthode.
  2. Vous avez besoin de l'annotation @RequestMapping pour que Spring la détecte.
22
uthark

L'interface de MessageConverter http://static.springsource.org/spring/docs/3.0.x/javadoc-api/ définit une méthode getSupportedMediaTypes (), qui dans le cas de MappingJacksonMessageCoverter renvoie application/json

public MappingJacksonHttpMessageConverter() {
    super(new MediaType("application", "json", DEFAULT_CHARSET));
}

Je suppose qu'un en-tête demande: application/json est manquant. 

3
Sven Haiges

Cela a fonctionné pour moi:

@RequestMapping(value = "{p_LocationId}.json", method = RequestMethod.GET)
protected void getLocationAsJson(@PathVariable("p_LocationId") Integer p_LocationId,
     @RequestParam("cid") Integer p_CustomerId, HttpServletResponse response) {
        MappingJacksonHttpMessageConverter jsonConverter = 
                new MappingJacksonHttpMessageConverter();
        Location requestedLocation = new Location(p_LocationId);
        MediaType jsonMimeType = MediaType.APPLICATION_JSON;
        if (jsonConverter.canWrite(requestedLocation.getClass(), jsonMimeType)) {
        try {
            jsonConverter.write(requestedLocation, jsonMimeType,
                                   new ServletServerHttpResponse(response));
            } catch (IOException m_Ioe) {
                // TODO: announce this exception somehow
            } catch (HttpMessageNotWritableException p_Nwe) {
                // TODO: announce this exception somehow
            }
        }
}

Notez que la méthode ne retourne rien: MappingJacksonHttpMessageConverter#write() fait la magie.

3
Boris Brudnoy

Une erreur HTTP 404 signifie simplement que la ressource est introuvable. Cela peut avoir 2 causes:

  1. L'URL de demande est incorrecte (erreur côté client ou URL incorrecte dans le lien/bouton donné).
  2. La ressource n'est pas là où vous vous attendez (erreur côté serveur).

Pour résoudre le problème 1, assurez-vous que vous utilisez ou fournissez l'URL de demande correcte (sensible à la casse!). Pour résoudre le problème 2, recherchez les erreurs de démarrage dans les journaux de démarrage du serveur et corrigez-les en conséquence.

Tout cela va au-delà du code et des informations affichés à ce jour.

2
BalusC

J'ai trouvé que j'avais également besoin de jackson-core-asl.jar, pas seulement jackson-mapper-asl.jar

1
ricor

En plus des réponses ici ..

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

Java:

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

Jquery (vous devez inclure le fichier json2.js de Douglas Crockford pour pouvoir utiliser 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');
    }
});
0
rafael lean ansay

Ceci est juste une hypothèse, mais par défaut, Jackson ne détecte que les champs publics (et les accesseurs publics; mais tous les paramètres indépendamment de la visibilité). Il est possible de configurer cela (avec la version 1.5 ) pour détecter automatiquement les champs privés si cela est souhaité (voir ici pour plus de détails).

0
StaxMan

Je suppose que 404 n’est pas lié à votre HttpMessageConverter. J'avais le même problème 404 et la raison était que j'avais oublié que seules les demandes correspondant à<url-pattern>étaient envoyées à DispatcherServlet (j'ai changé le mappage de demande de * .do à * .json). Peut-être que c'est aussi ton cas.

0