Spring MVC и REST
Spring - MVC фреймфорк, использующий аннотации, которые позволяют облегчить процесс создания RESTfull веб-сервиса. Основная разница между традиционным Spring MVC контроллером и RESTfull веб-сервис контроллером заключается в способе создания тела HTTP ответа. MVC контроллер опирается на технологию View, а RESTfull веб сервис контроллер возвращает объект, который представляется в HTTP ответе в виде JSON или XML. Для более подробного описания перейдите на эту ссылку.
Схема работы Spring MVC
- Клиент отправляет запрос к веб-сервису.
- Запрос перехватывается DispatcherServlet, который ищет Handler Mappings и соответствующий тип.
- Запрос обрабатывается контроллером и результат передается DispatcherServlet, а потом перенаправляется во view.
Использование @ResponseBody
Когда вы используете аннотацию @ResponseBody для метода, Spring автоматически записывает результат в тело http ответа. Каждый метод в контроллере должен иметь данную аннотацию. Схема работы представлена на рисунке 1.
Рисунок 1. |
Что происходит внутри
У Spring есть список HttpMessageConverters. HttpMessageConverter обязан конвертировать тело запроса к определенному классу и и класс к телу ответа, в зависимости от типа. Каждый раз, когда происходит запрос с аннотацией @ResponseBody, Spring ищет среди всех HttpMessageConverters подходящий и использует его.
Пример
Рассмотрим POJO класс:
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Employee") public class Employee { String name; String email; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Employee() { } }И класс с аннотацией @Controller:
import org.springframework.stereotype.Controller; 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.ResponseBody; import com.example.spring.model.Employee; @Controller @RequestMapping("employees") public class EmployeeController { Employee employee = new Employee(); @RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json") public @ResponseBody Employee getEmployeeInJSON(@PathVariable String name) { employee.setName(name); employee.setEmail("employee1@genuitec.com"); return employee; } @RequestMapping(value = "/{name}.xml", method = RequestMethod.GET, produces = "application/xml") public @ResponseBody Employee getEmployeeInXML(@PathVariable String name) { employee.setName(name); employee.setEmail("employee1@genuitec.com"); return employee; } }В результате получим:
JSON: http://localhost:8080/SpringRestControllerExample/rest/employees/Bob
XML: http://localhost:8080/SpringRestControllerExample/rest/employees/Bob.xml
Использование аннотации @RestController
В Spring 4.0 была представлена аннотация @RestController. Применив ее к контроллеру добавляются аннотации @Controller, а так же @ResponseBody применяется ко всем методам. Подробнее можно почитать здесь. Схема работы на рисунке 2.
Рассмотрим этот же пример, но с новой аннотацией, POJO- класс не изменится, а контроллер примет следующий вид:
package com.example.spring.rest; 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.example.spring.model.Employee; @RestController @RequestMapping("employees") public class EmployeeController { Employee employee = new Employee(); @RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json") public Employee getEmployeeInJSON(@PathVariable String name) { employee.setName(name); employee.setEmail("employee1@genuitec.com"); return employee; } @RequestMapping(value = "/{name}.xml", method = RequestMethod.GET, produces = "application/xml") public Employee getEmployeeInXML(@PathVariable String name) { employee.setName(name); employee.setEmail("employee1@genuitec.com"); return employee; } }Заметьте, что не нужно добавлять @ResponseBody к каждому методу. Запустив приложение - получим тот же результат.
PS это мой перевод данной статьи
Не @RequestBody,а @ResponseBody
ОтветитьУдалитьПоверяйте правильность стати перед публикацией пожалуйста.
DispatcherServlet - ошибочка в начале статьи
ОтветитьУдалитьthanks!
ОтветитьУдалитьМожно еще короче - @RequestMapping заменить на @GetMapping/@PostMapping/@DeleteMapping...
ОтветитьУдалитьНапряжная статья, в Java доке куда очевиднее.
ОтветитьУдалитьхорошая статья
ОтветитьУдалить