Was ist zurückzugeben, wenn die Spring MVC-Controller-Methode keinen Wert zurückgibt?


135

Ich verwende jQuery's $.getJSON(), um asynchrone Aufrufe an mein einfaches Spring MVC-Backend zu tätigen. Die meisten Spring-Controller-Methoden sehen folgendermaßen aus:

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) {
    return someDAO.getSomeData(widget, type);
}   

Ich habe Dinge so eingerichtet, dass jeder Controller das @ResponseBodyals JSON zurückgibt , was die Clientseite erwartet.

Aber was passiert, wenn eine Anfrage keinen Inhalt an den Client zurückgeben soll? Kann ich haben:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Wenn nicht, welche Syntax ist hier zu verwenden?


Ich nehme an, wenn Sie nichts zurückgeben, werden keine Inhalte zurückgesendet?
Arahant

1
Ich denke, ich würde immer noch ein POJO zurückgeben, selbst wenn es in Version 1 Ihrer Lösung nur einen "Erfolgs" -Booleschen Wert oder ähnliches enthält. Dann haben Sie ein konsistentes Muster in all Ihren AJAX-Methoden und etwas, auf das Sie leichter aufbauen können, wenn sich herausstellt, dass Sie etwas zurückgeben müssen!
Mühlenhaus

Im Gegensatz zu den vorgeschlagenen Vorschlägen ist das, was Sie zuerst in Ihrem zweiten Snippet hatten, vollkommen in Ordnung und der richtige Umgang mit POSTDaten.
Brett Ryan

In diesem Fall wird null zurückgegeben. @RestController öffentliche Klasse RESTControllerExample {@RequestMapping (value = "/ employee", method = RequestMethod.GET) public void getEmployeeNames () {EmployeeSource.getEmployees (); System.out.println ("Ich bin fertig"); }}
Spandey

Antworten:


256

Sie können void zurückgeben, dann müssen Sie die Methode mit @ResponseStatus (value = HttpStatus.OK) markieren. Sie benötigen @ResponseBody nicht

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Nur Get-Methoden geben eine Implizität von 200 Statuscodes zurück. Alle anderen Methoden haben eines von drei Dingen:

  • Geben Sie void zurück und markieren Sie die Methode mit @ResponseStatus(value = HttpStatus.OK)
  • Ein Objekt zurückgeben und mit markieren @ResponseBody
  • Rückgabe eines HttpEntity Instanz zurück

2
Falls dazwischen eine Laufzeitausnahme auftritt, wird HTTP 500 zurückgegeben und nicht 200. Wenn also Ihr Front-End-Handle ausfällt, wird die Ausnahme- / Fehlermeldung korrekt angezeigt.
Lee Chee Kiam

27
Eigentlich müssen Sie nicht einstellen @ResponseStatusund sollten nicht. Es ist schon gut genug , @ResponseBodyeinen voidHandler zu haben.
Brett Ryan

11
Ich denke, es wird besser sein, einen 204 No Content anstelle eines 200 für void-Methoden zurückzugeben
raspacorp

1
@raspacorp 200 ist für POST korrekt, da es keinen Körper haben soll.
Brett Ryan

8
@BrettRyan Nur als Kommentar, zumindest für eine REST-API, ist es üblich, dass ein POST zum Erstellen von Inhalten verwendet wird. In diesem Fall wird normalerweise die ID der erstellten Enity (s), der vollständig erstellten Entitäten oder eines Links zurückgegeben zum Lesevorgang. Eine 200-Status-Rückgabe ohne Inhalt kann aus Sicht der REST-API verwirrend sein.
Raspacorp

43

Sie können einfach eine ResponseEntity mit dem entsprechenden Header zurückgeben:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}

Wenn jemand auf das gleiche Problem stieß, das ich hatte, funktionierte dies bei einer älteren Version von Spring (4.1.1) nicht. Ich würde 500 Fehler erhalten. Ich habe auf 4.2.0 aktualisiert und das funktioniert super
Sauce

Das ist meine bevorzugte Art, auch leere 200 zurückzugeben. Verwenden Sie seit Spring 4.1 stattdessen das Builder-Muster: return ResponseEntity.ok (). Build ();
GreenTurtle

3
Obwohl es zu kompilieren scheint, gibt es die folgende WarnungResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized
Gonzalo.-

8

Sie können das Objekt "ResponseEntity" zurückgeben. Die Verwendung des Objekts "ResponseEntity" ist sowohl zum Zeitpunkt der Erstellung des Antwortobjekts (das den Antworttext und den HTTP-Statuscode enthält) als auch zum Zeitpunkt des Abrufs von Informationen aus dem Antwortobjekt sehr praktisch.

Methoden wie getHeaders (), getBody (), getContentType (), getStatusCode () usw. erleichtern das Lesen des ResponseEntity-Objekts.

Sie sollten das ResponseEntity-Objekt mit dem http-Statuscode 204 (No Content) verwenden. Dies soll insbesondere angeben, dass die Anforderung ordnungsgemäß verarbeitet wurde und der Antworttext absichtlich leer ist. Die Verwendung geeigneter Statuscodes zur Übermittlung der richtigen Informationen ist sehr wichtig, insbesondere wenn Sie eine API erstellen, die von mehreren Clientanwendungen verwendet werden soll.


3
Einstellung für mich im Browser @ResponseStatus(HttpStatus.NO_CONTENT)gelöstXML Parsing Error: no root element found
Aliopi

3

Ja, Sie können @ResponseBody mit dem voidRückgabetyp verwenden:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

1
Was ist der Rückgabetyp? Ist es ein HTTP-Statuscode?
Spandey

@techBeginner In diesem Fall 200 (OK).
Lakatos Gyula

2

Es ist nichts Falsches daran, eine Leere zurückzugeben, @ResponseBodyund Sie sollten dafürPOST Anfragen .

Verwenden Sie stattdessen HTTP-Statuscodes, um Fehler in Ausnahmehandlerroutinen zu definieren, da andere den Erfolgsstatus erwähnen. Eine normale Methode, wie Sie sie haben, gibt einen Antwortcode zurück, von 200dem Sie möchten. Jeder Ausnahmebehandler kann dann ein Fehlerobjekt und einen anderen Code (dh 500) zurückgeben.


1

Aber wenn Ihr System an Größe und Funktionalität zunimmt, denke ich, dass es überhaupt keine schlechte Idee ist, immer einen JSON zurückzugeben. Ist eher eine architektonische / "groß angelegte Design" Angelegenheit.

Sie können daran denken, immer einen JSON mit zwei bekannten Feldern zu speichern: Code und Daten. Wobei Code ein numerischer Code ist, der den Erfolg der auszuführenden Operation angibt, und Daten alle zusätzlichen Daten sind, die sich auf die angeforderte Operation / den angeforderten Dienst beziehen.

Komm schon, wenn wir ein Backend eines Dienstanbieters verwenden, kann jeder Dienst überprüft werden, um festzustellen, ob er gut funktioniert hat.

Ich halte mich also daran, dass Spring dies nicht verwaltet und hybride Rückgabevorgänge verfügbar macht (einige geben Daten zurück, andere nichts ...). Stellen Sie sicher, dass Ihr Server eine homogenere Schnittstelle bereitstellt. Ist am Ende des Tages einfacher.


0

Hier ist Beispielcode, was ich für eine asynchrone Methode getan habe

@RequestMapping(value = "/import", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{
    accountingSystemHandler.importData(file, assignChargeCodes);
}

Sie müssen nichts von Ihrer Methode zurückgeben, sondern nur diese Annotation verwenden, damit Ihre Methode in jedem Fall OK zurückgibt

@ResponseStatus(value = HttpStatus.OK)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.