Anmerkungen zu @RequestBody und @ResponseBody im Frühjahr

138

Kann jemand die @RequestBodyund @ResponseBodyAnmerkungen im Frühjahr 3 erklären ? Wofür sind sie? Alle Beispiele wären toll.

Löwe
quelle

Antworten:

218

In den Dokumenten gibt es einen ganzen Abschnitt mit dem Namen 16.3.3.4 . Zuordnen des Anforderungshauptteils mit der Annotation @RequestBody . Und einer namens 16.3.3.5 Mapping des Antwortkörpers mit der Annotation @ResponseBody . Ich schlage vor, Sie konsultieren diese Abschnitte. Ebenfalls relevant: @RequestBodyJavadocs, @ResponseBodyJavadocs

Verwendungsbeispiele wären ungefähr so:

Mit einer JavaScript-Bibliothek wie JQuery würden Sie ein JSON-Objekt wie folgt posten:

{ "firstName" : "Elmer", "lastName" : "Fudd" }

Ihre Controller-Methode würde folgendermaßen aussehen:

// controller
@ResponseBody @RequestMapping("/description")
public Description getDescription(@RequestBody UserStats stats){
    return new Description(stats.getFirstName() + " " + stats.getLastname() + " hates wacky wabbits");
}

// domain / value objects
public class UserStats{
    private String firstName;
    private String lastName;
    // + getters, setters
}
public class Description{
    private String description;
    // + getters, setters, constructor
}

Wenn Sie nun Jackson in Ihrem Klassenpfad haben (und ein <mvc:annotation-driven>Setup haben), konvertiert Spring den eingehenden JSON aus dem Post-Body in ein UserStats-Objekt (weil Sie die @RequestBodyAnnotation hinzugefügt haben ) und serialisiert das zurückgegebene Objekt in JSON (weil Sie das hinzugefügt haben) @ResponseBodyAnmerkung). Der Browser / Client würde also dieses JSON-Ergebnis sehen:

{ "description" : "Elmer Fudd hates wacky wabbits" }

In meiner vorherigen Antwort finden Sie ein vollständiges Arbeitsbeispiel: https://stackoverflow.com/a/5908632/342852

Hinweis: RequestBody / ResponseBody ist natürlich nicht auf JSON beschränkt. Beide können mehrere Formate verarbeiten, einschließlich Klartext und XML. JSON ist jedoch wahrscheinlich das am häufigsten verwendete Format.


Aktualisieren

Seit Spring 4.x werden Sie normalerweise nicht mehr @ResponseBodyauf Methodenebene, sondern @RestControllerauf Klassenebene mit demselben Effekt verwenden.

Hier ist ein Zitat aus der offiziellen Spring MVC-Dokumentation :

@RestControllerist eine zusammengesetzte Annotation , die selbst mit einem Controller meta-annotiert ist@Controller und @ResponseBodyeinen Controller angibt, dessen jede Methode die @ResponseBodyAnnotation auf Typebene erbt und daher direkt in den Antworttext im Vergleich zur Ansichtsauflösung und zum Rendern mit einer HTML-Vorlage schreibt.

Sean Patrick Floyd
quelle
In Ihrer verknüpften Antwort haben Sie die @ResponseBodyAnmerkung zum Parameter und nicht die Methode verwendet. Ich erhalte Fehler beim Versuch, es auf die Methode zu setzen, daher gehe ich davon aus, dass Ihre andere Antwort richtig ist. Ich denke du solltest getDescription(@RequestBody UserStats stats)oben haben.
Patrick
3
@Patrick nein, @RequestBodyist auf dem Parameter, @ResponseBodyist auf der Methode. wichtiger Unterschied!
Sean Patrick Floyd
1
@ SeanPatrickFloyd Entschuldigung, ich wollte das überhaupt nicht erwähnen @ResponseBody. Wie Sie gerade gesagt haben, @RequestBodygeht auf den Parameter, richtig? Aber in der obigen Antwort haben Sie es auf der Methode.
Patrick
1
@SeanPatrickFloyd @RequestBodyist eigentlich noch erforderlich, @ResponseBodyist bei der Verwendung implizit @RestController. Bitte korrigieren Sie Ihre Antwort, es hat zu viele positive Stimmen, um falsch zu sein!
Sumit Jain
@ SumitJain um fair zu sein: Diese Antwort gab es schon früher @RestControllerund wurde geändert, als sie eingeführt wurde
Sean Patrick Floyd
32

@RequestBody : Eine Anmerkung, die einen Methodenparameter angibt, sollte an den Hauptteil der HTTP-Anforderung gebunden werden.

Beispielsweise:

@RequestMapping(path = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
    writer.write(body);
}

Die @ ResponseBody- Annotation kann in eine Methode eingefügt werden und gibt an, dass der Rückgabetyp direkt in den HTTP-Antworttext geschrieben (und nicht in ein Modell eingefügt oder als Ansichtsname interpretiert werden soll).

Beispielsweise:

@RequestMapping(path = "/something", method = RequestMethod.PUT)
public  @ResponseBody String helloWorld() {
    return "Hello World";
}  

Alternativ können wir anstelle der Annotation auch die @ RestController-@Controller Annotation verwenden. Dadurch entfällt die Notwendigkeit der Verwendung @ResponseBody.

für mehr Details

Premraj
quelle
5

Unten finden Sie ein Beispiel für eine Methode in einem Java-Controller.

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public HttpStatus something(@RequestBody MyModel myModel) 
{
    return HttpStatus.OK;
}

Wenn Sie die Annotation @RequestBody verwenden, werden Ihre Werte dem Modell zugeordnet, das Sie in Ihrem System für die Bearbeitung eines bestimmten Anrufs erstellt haben. Mit @ResponseBody können Sie alles an den Ort zurücksenden, von dem aus die Anforderung generiert wurde. Beide Dinge können einfach zugeordnet werden, ohne dass ein benutzerdefinierter Parser usw. geschrieben werden muss.

AbdusSalam
quelle
1
package com.programmingfree.springshop.controller;

import java.util.List;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.programmingfree.springshop.dao.UserShop;
import com.programmingfree.springshop.domain.User;


@RestController
@RequestMapping("/shop/user")
public class SpringShopController {

 UserShop userShop=new UserShop();

 @RequestMapping(value = "/{id}", method = RequestMethod.GET,headers="Accept=application/json")
 public User getUser(@PathVariable int id) {
  User user=userShop.getUserById(id);
  return user;
 }


 @RequestMapping(method = RequestMethod.GET,headers="Accept=application/json")
 public List<User> getAllUsers() {
  List<User> users=userShop.getAllUsers();
  return users;
 }


}

Im obigen Beispiel werden jetzt alle Benutzer- und bestimmten ID-Details angezeigt. Ich möchte sowohl die ID als auch den Namen verwenden.

1) localhost: 8093 / plejson / shop / user <--- Dieser Link zeigt alle Benutzerdetails an.
2) localhost: 8093 / plejson / shop / user / 11 <---- Wenn ich 11 in Link-Mitteln verwende, wird dies der Fall sein Anzeige bestimmter Benutzer 11 Details

Jetzt möchte ich sowohl ID als auch Name verwenden

localhost: 8093 / plejson / shop / user / 11 / raju <----------------- so bedeutet dies, dass wir jeden verwenden können, bitte helfen Sie mir ... .

user5409646
quelle
Bitte korrigieren Sie die Formatierung der Antwort und des Codebeispiels.
Maciej Lach
Bitte beschreiben Sie, wie dieser Code dem Fragesteller hilft. Danke dir.
Leonid Glanz
programme-free.com/2014/03/… .................... gehe über diesen Link und erhalte ... danke
user5409646
programmieren-frei.com/2014/03/… ....................................... .................................................. ..... gehe durch diesen Link und du wirst es dir danken
user5409646