wake-up-neo.net

Spring 3.0 macht JSON-Antwort mit Jackson Message Converter

ich konfiguriere meinen Nachrichtenkonverter dann als Jackson

class Foo{int x; int y}

und im Controller

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

ich erwarte, einen JSON-String {x: '3', y: '4'} vom Server ohne andere Konfiguration zurückzugeben. aber 404 Fehlerantwort auf meine Ajax-Anfrage erhalten 

Wenn die Methode mit @ResponseBody kommentiert wird, wird der Rückgabetyp in den Antwort-HTTP-Body geschrieben. Der Rückgabewert wird mit HttpMessageConverters in den deklarierten Methodenargumenttyp konvertiert.

Liege ich falsch ? oder sollte ich mein Antwortobjekt selbst in einen Json-String konvertieren, indem ich den Serializer verwende und diesen String dann als Antwort zurücksende. wie das Hinzufügen von Anmerkungen für die Klasse Foo 

hier ist meine 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

Sie benötigen Folgendes:

  1. Anmerkungsgesteuertes Programmiermodell festlegen: <mvc:annotation-driven /> in spring.xml setzen
  2. Platzieren Sie jaskson jar (Maven ArtifactId ist org.codehaus.jackson:jackson-mapper-asl) im Klassenpfad.
  3. Verwenden Sie wie folgt:

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

Das funktioniert für mich.

Bitte beachte, dass 

  1. @ResponseBody wird auf den Rückgabetyp angewendet, nicht auf die Methodendefinition.
  2. Sie benötigen eine @RequestMapping-Anmerkung, damit Spring sie erkennt.
22
uthark

Die MessageConverter-Schnittstelle http://static.springsource.org/spring/docs/3.0.x/javadoc-api/ definiert eine getSupportedMediaTypes () - Methode, die im Falle des MappingJacksonMessageCoverter application/json zurückgibt

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

Ich gehe davon aus, dass ein Anforderungsheader Accept: application/json fehlt. 

3
Sven Haiges

Das hat für mich funktioniert:

@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
            }
        }
}

Beachten Sie, dass die Methode nichts zurückgibt: MappingJacksonHttpMessageConverter#write() zaubert.

3
Boris Brudnoy

Ein HTTP 404-Fehler bedeutet nur, dass die Ressource nicht gefunden werden kann. Das kann zwei Ursachen haben:

  1. Anforderungs-URL ist falsch (clientseitiger Fehler oder falsche URL in angegebenem Link/Schaltfläche).
  2. Die Ressource ist nicht dort, wo Sie sie erwarten (serverseitiger Fehler).

Um Problem 1 zu beheben, stellen Sie sicher, dass Sie die richtige Anforderungs-URL verwenden oder angeben (Groß- und Kleinschreibung beachten!). Um Problem zu beheben, überprüfen Sie die Server-Startprotokolle auf Startfehler und beheben Sie sie entsprechend.

Dies alles geht über den bisher veröffentlichten Code und die Informationen hinaus.

2
BalusC

Ich fand, dass ich auch Jackson-Core-asl.jar brauche, nicht nur Jackson-Mapper-asl.

1
ricor

Neben den Antworten hier ..

wenn Sie Jquery auf der Clientseite verwenden, hat dies für mich funktioniert:

Java:

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

Jquery (Sie müssen Douglas Crockfords json2.js hinzufügen, um die JSON.stringify-Funktion zu erhalten):

$.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

Dies ist nur eine Vermutung, aber standardmäßig erkennt Jackson nur öffentliche Felder (und öffentliche Getter; alle Setter unabhängig von der Sichtbarkeit) automatisch. Sie können dies konfigurieren (mit Version 1.5 ), um auch private Felder automatisch zu erkennen, wenn dies gewünscht wird (siehe hier für Details).

0
StaxMan

Ich denke, dass 404 nicht mit Ihrem HttpMessageConverter zusammenhängt. Ich hatte dasselbe 404-Problem und der Grund war, dass ich vergessen habe, dass nur Anforderungen, die mit<url-pattern>übereinstimmen, an DispatcherServlet gesendet werden (ich habe die Anforderungszuordnung von * .do in * .json geändert). Vielleicht ist das auch dein Fall.