Вступление
В Spring мы сопоставляем запросы с обработчиками запросов через
аннотацию @RequestMapping
Spring Boot познакомил нас с производными
типами этой аннотации - @GetMapping
, @PostMapping
,
@DeleteMapping
и т. Д.
Эти запросы содержат разные типы информации и данных - и в зависимости
от того, что наша конечная точка делает с запросом, мы можем захотеть
получить тело POST
либо для регистрации, либо для дальнейшей
обработки.
@RequestBody
позволяет нам получить тело запроса. Затем мы можем
вернуть его как строку или десериализовать в простой старый объект
Java (POJO).
Spring имеет встроенные механизмы для десериализации объектов JSON и XML в POJO, что также значительно упрощает эту задачу.
В этой статье мы получим тело POST
и упакуем его в строку, а также
десериализуем его в POJO.
Получение тела HTTP POST в виде строки
Начнем с @Controller
для обработки входящего запроса:
@ResponseBody
@Controller
@RequestMapping("/response")
public class HomeController {}
Здесь стоит отметить, что мы добавили аннотацию @ResponseBody
@Controller
. Таким образом, он не будет отображать шаблон в качестве
тела ответа, а скорее вернет тело ответа. В частности, мы упакуем его в
строку и вернем ее.
Spring Boot познакомил нас с другим производным типом -
@RestController
который представляет собой просто комбинацию двух
предыдущих аннотаций. Давайте использовать это вместо этого для
краткости:
@RestController
@RequestMapping("/response")
public class HomeController {}
Теперь давайте продолжим и определим обработчик запросов. Поскольку мы
обрабатываем POST
, мы будем использовать для @PostMapping
аннотацию
@PostMapping:
@RestController
@RequestMapping("/response")
public class HomeController {
@PostMapping("/postbody")
public String postBody(@RequestBody String fullName) {
return "Hello " + fullName;
}
}
Чтобы получить тело POST
отправленного обработчику, мы будем
использовать @RequestBody
и присвоить ее значение String. Он берет
тело запроса и аккуратно упаковывает его в нашу строку fullName
Затем
мы вернули это имя обратно с приветственным сообщением.
Давайте протестируем этот контроллер через curl
:
curl -X POST -H "Content-type: application/json" -d "John Smith" "http://localhost:8080/response/postbody"
Это приводит к:
Hello John Smith
Десериализовать HTTP POST в POJO
Обычно мы не будем работать со строками, хотя они служат хорошим
примером для обучения. В большинстве случаев нам нужно выполнить
некоторую обработку или, по крайней мере, сериализовать запрос в POJO.
Давайте определим POJO Person
firstName
и lastName
:
public class Person {
private String firstName;
private String lastName;
// Constructor, getters and setters
}
Мы выполним тот же процесс, что и в предыдущем примере, с тем же контроллером. Однако на этот раз мы укажем, что контроллер принимает значения JSON и XML и возвращает ответы JSON или XML.
Мы POST
тело запроса POST в формате JSON, десериализуем его в POJO для
дальнейшей обработки (например, для сохранения в базе данных) и вернем
ответ JSON.
Хотя Spring Boot может автоматически сопоставить тело JSON с нашим POJO,
учитывая совпадение имен переменных, мы явно установим эту опцию. Мы
установим входные и выходные форматы с использованием consumes
и
produces
флаги в @PostMapping
:
@RestController
@RequestMapping("/response")
public class HomeController {
@PostMapping(
value = "/postbody",
consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<Person> postBody(@RequestBody Person person) {
Person persistedPerson = personService.save(person);
return ResponseEntity
.created(URI
.create(String.format("/persons/%s", person.getFirstName())))
.body(persistedPerson);
}
}
Здесь мы принимаем JSON и XML, а также возвращаем их обратно. Мы
аннотировали экземпляр Person
@RequestBody
, чего мы также будем
ожидать от запроса. Затем мы использовали PersonService
чтобы
сохранить человека в базе данных, которая также возвращает сохраненный
объект для дальнейшей обработки.
Для краткости мы опустили PersonService
поскольку это стандартная
реализация уровня сервиса.
Наконец, мы вернули объект ResponseEntity
Это просто расширение
HttpEntity
которое также имеет код состояния. Мы установили код
состояния как CREATED
с URI
котором находится новый созданный
ресурс. Затем мы установили тело ResponseEntity
как persistentPerson
и построили ответ.
Давайте снова протестируем этот контроллер через curl
:
curl -X POST -H "Content-type: application/json" -d "{\"firstName\" : \"John\", \"lastName\" : \"Smith\"}" "http://localhost:8080/response/postbody"
Здесь мы сделали POST
с телом JSON, содержащим имя и фамилию человека,
и отправили его на нашу конечную точку.
Конечная точка отвечает:
{"firstName":"John","lastName":"Smith"}
Заключение
В этом руководстве мы рассмотрели два способа захвата POST
в
контроллере Spring Boot.
Используя @RequestBody
, мы сопоставили тело с String и вернули его.
Впоследствии мы определили POJO для десериализации входящего содержимого
JSON, обработали его и, наконец, вернули ResponseEntity
.