Annotations @RequestBody et @ResponseBody au printemps

139

Quelqu'un peut-il expliquer les annotations @RequestBodyet @ResponseBodyau printemps 3? À quoi servent-ils? Tout exemple serait génial.

Leo
la source

Réponses:

219

Il y a une section entière dans la documentation appelée 16.3.3.4 Mappage du corps de la requête avec l'annotation @RequestBody . Et l'un a appelé 16.3.3.5 Mappage du corps de la réponse avec l'annotation @ResponseBody . Je vous suggère de consulter ces sections. Aussi pertinent: @RequestBodyjavadocs, @ResponseBodyjavadocs

Les exemples d'utilisation seraient quelque chose comme ceci:

En utilisant une bibliothèque JavaScript comme JQuery, vous publierez un objet JSON comme celui-ci:

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

Votre méthode de contrôleur ressemblerait à ceci:

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

Maintenant, si vous avez Jackson sur votre chemin de classe (et avez une <mvc:annotation-driven>configuration), Spring convertirait le JSON entrant en objet UserStats à partir du corps de l'article (car vous avez ajouté le@RequestBody annotation) et il sérialiserait l'objet retourné en JSON (parce que vous avez ajouté le @ResponseBodyannotation). Ainsi, le navigateur / client verrait ce résultat JSON:

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

Voir ma réponse précédente pour un exemple de travail complet: https://stackoverflow.com/a/5908632/342852

Remarque: RequestBody / ResponseBody n'est bien sûr pas limité à JSON, les deux peuvent gérer plusieurs formats, y compris le texte brut et XML, mais JSON est probablement le format le plus utilisé.


Mettre à jour

Depuis le printemps 4.x, vous n'utiliserez généralement pas @ResponseBodyau niveau de la méthode, mais plutôt@RestController au niveau de la classe, avec le même effet.

Voici une citation de la documentation officielle de Spring MVC :

@RestControllerest une annotation composée qui est elle - même méta-annotée avec @Controlleret @ResponseBodypour indiquer un contrôleur dont chaque méthode hérite de l' @ResponseBodyannotation au niveau du type et, par conséquent, écrit directement dans le corps de la réponse par rapport à la résolution de la vue et au rendu avec un modèle HTML.

Sean Patrick Floyd
la source
Dans votre réponse liée, vous avez utilisé l' @ResponseBodyannotation sur le paramètre, pas la méthode. Je reçois des erreurs en essayant de le mettre sur la méthode, donc je suppose que votre autre réponse est correcte. Je pense que vous devriez avoir getDescription(@RequestBody UserStats stats)ci - dessus.
Patrick
3
@Patrick non, @RequestBodyest sur le paramètre, @ResponseBodyest sur la méthode. différence importante!
Sean Patrick Floyd
1
@SeanPatrickFloyd Désolé, je ne voulais pas du tout mentionner @ResponseBody. Comme vous venez de le dire, @RequestBodypasse au paramètre, non? Mais dans la réponse ci-dessus, vous l'avez sur la méthode.
Patrick
1
@SeanPatrickFloyd @RequestBodyest en fait toujours requis, @ResponseBodyest implicite lors de l'utilisation @RestController. Veuillez corriger votre réponse, il y a trop de votes positifs pour être faux!
Sumit Jain
@SumitJain pour être juste: cette réponse existait avant @RestControlleret a été modifiée lorsqu'elle a été introduite
Sean Patrick Floyd
32

@RequestBody : Annotation indiquant qu'un paramètre de méthode doit être lié au corps de la requête HTTP.

Par exemple:

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

@ResponseBody annotation peut être placée sur une méthode et indique que le type de retour doit être écrit directement dans le corps de la réponse HTTP (et non placé dans un modèle, ou interprété comme un nom de vue).

Par exemple:

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

Alternativement, nous pouvons utiliser l' annotation @RestController à la place de l' @Controllerannotation. Cela supprimera le besoin d'utiliser @ResponseBody.

pour plus de détails

Premraj
la source
5

Voici un exemple de méthode dans un contrôleur Java.

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

En utilisant l'annotation @RequestBody, vous obtiendrez vos valeurs mappées avec le modèle que vous avez créé dans votre système pour traiter tout appel spécifique. En utilisant @ResponseBody, vous pouvez tout renvoyer à l'endroit d'où la demande a été générée. Les deux choses seront facilement mappées sans écrire aucun analyseur personnalisé, etc.

AbdusSalam
la source
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;
 }


}

Dans l'exemple ci-dessus, ils vont afficher tous les détails d'utilisateur et d'identifiant particulier maintenant, je veux utiliser à la fois l'identifiant et le nom,

1) localhost: 8093 / plejson / shop / user <--- ce lien affichera tous les détails de l'utilisateur
2) localhost: 8093 / plejson / shop / user / 11 <---- si j'utilise 11 dans le lien signifie, il sera afficher les détails de l'utilisateur particulier 11

maintenant je veux utiliser à la fois l'identifiant et le nom

localhost: 8093 / plejson / shop / user / 11 / raju <----------------- comme ceci, cela signifie que nous pouvons utiliser n'importe lequel dans ce cas, veuillez m'aider .... .

user5409646
la source
Veuillez corriger le formatage de la réponse et l'exemple de code.
Maciej Lach
Veuillez décrire comment ce code aide le questionneur. Je vous remercie.
Leonid Glanz
programmation-free.com/2014/03/ ... .................... passez par ce lien vous obtiendrez ... merci
user5409646
programmation-free.com/2014/03/ ... ....................................... .................................................. ..... passez par ce lien vous obtiendrez des remerciements
user5409646