Аннотации @Controller и @RestController в Spring Boot

Введение В Spring Boot класс контроллера отвечает за обработку входящих запросов REST API, подготовку модели и возврат представления, которое будет отображаться в качестве ответа. Классы контроллеров в Spring аннотируются аннотацией @Controller или @RestController. Они помечают классы контроллеров как обработчики запросов, чтобы Spring мог распознать их как службу RESTful во время выполнения. В этом руководстве мы рассмотрим определение @Controller и @RestControl.

Вступление

В Spring Boot класс контроллера отвечает за обработку входящих запросов REST API, подготовку модели и возврат представления для отображения в качестве ответа.

Классы контроллеров в Spring аннотируются аннотацией @Controller или @RestController . Они помечают классы контроллеров как обработчики запросов, чтобы Spring мог распознать их как службу RESTful во время выполнения.

В этом руководстве мы рассмотрим определение @Controller и @RestController , их варианты использования и разницу между двумя аннотациями.

Если вы новичок в Spring Boot, вы также можете ознакомиться с нашим полным руководством по созданию Spring Boot REST API .

Рабочий процесс Spring Boot REST API

Прежде чем определять две аннотации, мы быстро рассмотрим рабочий процесс того, как Spring Boot обрабатывает запросы и обработку REST API и возвращает ответ:

Пружина сервлетадиспетчера

Сначала запрос получает DispatcherServlet , который отвечает за обработку любых входящих запросов URI и сопоставление их с соответствующими обработчиками в виде методов контроллера. После выполнения метода контроллера ресурс обрабатывается как ответ, который может быть либо JSON, либо XML.

На приведенной выше диаграмме два процесса, заключенные в прямоугольник, являются процессами, фактически реализованными разработчиком. Остальные выполняются службами Spring, работающими в фоновом режиме, включая DispatcherServlet .

Аннотация @Controller

@Controller - это специализация универсальной стереотипной @Component , которая позволяет распознавать класс как управляемый Spring компонент.

@Controller расширяет возможности использования @Component и отмечает аннотированный класс как бизнес-уровень или уровень представления. Когда запрос сделан, это проинформирует DispatcherServlet о включении класса контроллера в сканирование методов, отображаемых аннотацией @RequestMapping

Теперь мы объявим фактический контроллер для определения бизнес-логики и обработки всех запросов, связанных с Tree модели.

Сначала отметьте класс @Controller вместе с @RequestMapping и укажите путь к /api/tree :

 @Controller 
 @ResponseBody 
 @RequestMapping("/api/tree") 
 public class TreeController { 
 
 @Autowired 
 private TreeRepository repository; 
 
 @GetMapping("/{id}") 
 public Tree getTreeById(@PathVariable int id) { 
 return repository.findById(id); 
 } 
 
 @GetMapping 
 public Tree getTreeById(@RequestParam String name, 
 @RequestParam int age) { 
 return repository.findFirstByCommonNameIgnoreCaseAndAge(name, age); 
 } 
 } 

@Autowired используется для автоматического внедрения зависимостей указанного типа в текущий bean-компонент. В этом случае TreeRepository компонент TreeRepository вводится как зависимость от TreeController .

@GetMapping - это ярлык для @RequestMapping(method = RequestMethod.GET) , который используется для сопоставления GET с сопоставленными методами контроллера.

Мы применили @ResponseBody к уровню класса этого контроллера. Когда обработчики запросов возвращают данные обратно, например return repository.findById() , ответ будет сериализован в JSON перед возвратом клиенту.

В качестве альтернативы вы могли бы аннотировать каждый тип @ResponseBody аннотацией @ResponseBody:

 @GetMapping("/{id}") 
 public @ResponseBody Tree getTreeById(@PathVariable int id) { 
 return repository.findById(id); 
 } 

Если мы запустим это приложение, предполагая, что у нас уже есть Tree сохраненный в базе данных, с идентификатором 1, и попадем в конечную точку localhost:8080/1

 {"species":"Salix babylonica","commonName":"Weeping willow", "age":"150"} 

Из-за @ResponseBody поля из извлеченного объекта сериализуются в JSON и возвращаются клиенту, который его запросил.

Аннотация @RestController

@RestController в Spring по сути представляют собой просто комбинацию @Controller и @ResponseBody . Эта аннотация была добавлена в Spring 4.0, чтобы удалить избыточность объявления @ResponseBody в вашем контроллере.

Это на одну аннотацию меньше! Если вы также посмотрите на определение интерфейса двух аннотаций, чтобы увидеть разницу между ними:

 @Target(ElementType.TYPE) 
 @Retention(RetentionPolicy.RUNTIME) 
 @Documented 
 @Controller 
 @ResponseBody 
 public @interface RestController { 
 //.. 
 } 
 
 @Target({ElementType.TYPE}) 
 @Retention(RetentionPolicy.RUNTIME) 
 @Documented 
 @Component 
 public @interface Controller { 
 //.. 
 } 

Интерфейс RestController аннотируется @Controller и @ResponseBody вместо того, чтобы напрямую аннотировать его с помощью @Component .

Если мы заменим аннотацию нашего контроллера на @RestController , нам не нужно будет изменять домен и уровень сохраняемости, поскольку они все равно будут совместимы с этой аннотацией.

TreeController выше пример контроллера TreeController, давайте сравним изменения, когда мы используем эту аннотацию:

 @RestController 
 @RequestMapping("/api/tree") 
 public class TreeController { 
 
 @Autowired 
 private TreeRepository repository; 
 
 @GetMapping("/{id}") 
 public Tree getTreeById(@PathVariable int id) { 
 return repository.findById(id); 
 } 
 
 @GetMapping 
 public Tree getTreeById(@RequestParam String name, 
 @RequestParam int age) { 
 return repository.findFirstByCommonNameIgnoreCaseAndAge(name, age); 
 } 
 } 

Теперь ко всем методам @ResponseBody аннотация @ResponseBody, поскольку @RestController применяет ее на уровне класса.

Если мы запустим это приложение, предполагая, что у нас уже есть Tree сохраненный в базе данных, с идентификатором 1, и попадем в конечную точку localhost:8080/1

 {"species":"Salix babylonica","commonName":"Weeping willow", "age":"150"} 

Заключение

По сути, @RestController расширяет возможности аннотаций @Controller и @ResponseBody

Помимо того факта, что @RestController существует для того, чтобы контроллеры Spring были на одну строку короче, между двумя аннотациями нет каких-либо серьезных различий.

Основная функция обеих аннотаций - позволить классу распознаваться как компонент, управляемый Spring, и разрешить обработку HTTP-запросов с использованием REST API.

comments powered by Disqus