@RequestBody i @ResponseBody na wiosnę

139

Czy ktoś może wyjaśnić adnotacje @RequestBodyi @ResponseBodyw Spring 3? Do czego służą? Wszelkie przykłady byłyby świetne.

Lew
źródło

Odpowiedzi:

219

W dokumentach znajduje się cała sekcja o nazwie 16.3.3.4 Mapowanie treści żądania z adnotacją @RequestBody . I o nazwie 16.3.3.5 Mapowanie treści odpowiedzi za pomocą adnotacji @ResponseBody . Proponuję zapoznać się z tymi sekcjami. Istotne również: @RequestBodyjavadocs,@ResponseBody javadocs

Przykłady użycia wyglądałyby mniej więcej tak:

Korzystając z biblioteki JavaScript, takiej jak JQuery, opublikowałbyś obiekt JSON w następujący sposób:

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

Twoja metoda kontrolera wyglądałaby następująco:

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

Teraz, jeśli masz Jacksona na swojej ścieżce klas (i masz <mvc:annotation-driven>konfigurację), Spring przekonwertuje przychodzące JSON na obiekt UserStats z treści posta (ponieważ dodałeś @RequestBodyadnotację) i serializuje zwrócony obiekt do JSON (ponieważ dodałeś @ResponseBodyadnotacja). Więc przeglądarka / klient zobaczy następujący wynik JSON:

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

Zobacz moją poprzednią odpowiedź, aby uzyskać pełny przykład roboczy: https://stackoverflow.com/a/5908632/342852

Uwaga: RequestBody / ResponseBody nie ogranicza się oczywiście do JSON, oba mogą obsługiwać wiele formatów, w tym zwykły tekst i XML, ale JSON jest prawdopodobnie najczęściej używanym formatem.


Aktualizacja

Od wiosny 4.x zwykle nie będziesz używać @ResponseBodyna poziomie metody, ale raczej@RestController na poziomie klasy, z takim samym efektem.

Oto cytat z oficjalnej dokumentacji Spring MVC :

@RestControllerjest złożoną adnotacją, która sama jest meta-adnotacją za pomocą @Controlleri w @ResponseBodycelu wskazania kontrolera, którego każda metoda dziedziczy @ResponseBodyadnotację na poziomie typu, a zatem zapisuje bezpośrednio do treści odpowiedzi w przeciwieństwie do rozdzielczości widoku i renderowania za pomocą szablonu HTML.

Sean Patrick Floyd
źródło
W połączonej odpowiedzi użyłeś @ResponseBodyadnotacji dotyczącej parametru, a nie metody. Przy próbie przypisania tego do metody pojawiają się błędy, więc zakładam, że druga odpowiedź jest poprawna. Myślę, że powinieneś mieć getDescription(@RequestBody UserStats stats)powyżej.
Patrick,
3
@Patrick nie, @RequestBodyjest na parametrze, @ResponseBodyjest na metodzie. ważna różnica!
Sean Patrick Floyd
1
@SeanPatrickFloyd Przepraszam, nie chciałem w ogóle wspominać @ResponseBody. Jak właśnie powiedziałeś, @RequestBodyidzie o parametr, prawda? Ale w powyższej odpowiedzi masz to na metodzie.
Patrick
1
@SeanPatrickFloyd @RequestBodyjest nadal wymagany, @ResponseBodyjest niejawny podczas używania @RestController. Proszę poprawić swoją odpowiedź, ma zbyt wiele głosów pozytywnych, aby być fałszywymi!
Sumit Jain
@SumitJain, aby być uczciwym: ta odpowiedź istniała wcześniej @RestControlleri została zmieniona, gdy została wprowadzona
Sean Patrick Floyd
32

@RequestBody : Adnotacja wskazująca parametr metody powinna być powiązana z treścią żądania HTTP.

Na przykład:

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

@ResponseBodyAdnotację można umieścić na metodzie i wskazać, że zwracany typ powinien zostać zapisany bezpośrednio w treści odpowiedzi HTTP (a nie umieszczony w modelu ani interpretowany jako nazwa widoku).

Na przykład:

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

Alternatywnie możemy użyć adnotacji @RestController zamiast @Controlleradnotacji. To usunie potrzebę używania @ResponseBody.

po więcej szczegółów

Premraj
źródło
5

Poniżej znajduje się przykład metody w kontrolerze Java.

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

Używając adnotacji @RequestBody, otrzymasz swoje wartości zmapowane z modelem utworzonym w systemie do obsługi dowolnego konkretnego wywołania. Korzystając z @ResponseBody, możesz odesłać wszystko z powrotem do miejsca, z którego zostało wygenerowane żądanie. Obie rzeczy zostaną łatwo zmapowane bez pisania niestandardowego parsera itp.

AbdusSalam
źródło
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;
 }


}

W powyższym przykładzie wyświetlą wszystkie dane użytkownika i szczegółowe dane identyfikacyjne, teraz chcę użyć zarówno identyfikatora, jak i nazwy,

1) localhost: 8093 / plejson / shop / user <--- ten link wyświetli wszystkie dane użytkownika
2) localhost: 8093 / plejson / shop / user / 11 <---- jeśli użyję 11 w linku oznacza, że ​​będzie wyświetl 11 szczegółów konkretnego użytkownika

teraz chcę użyć zarówno identyfikatora, jak i nazwy

localhost: 8093 / plejson / shop / user / 11 / raju <----------------- w ten sposób oznacza to, że możemy użyć dowolnego w tym, pomóż mi ... .

user5409646
źródło
Popraw formatowanie odpowiedzi i przykładowego kodu.
Maciej Lach
Opisz, w jaki sposób ten kod pomaga pytającemu. Dziękuję Ci.
Leonid Glanz
Programowanie-free.com/2014/03/ ... .................... przejdź przez ten link, a dostaniesz ... dziękuję
user5409646
Programowanie-free.com/2014/03/ ....................................... .................................................. ..... przejdź przez ten link, a otrzymasz podziękowanie
user5409646