Рубрики
Без рубрики

Аннотации @Controller и @RestController в весенней загрузке

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

Автор оригинала: Rayven Yor Esplanada.

Вступление

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

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

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

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

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

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

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

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

Аннотация @Controller

Аннотация @Controller является специализацией общего стереотипа @Компонента аннотации, которая позволяет распознавать класс как компонент, управляемый Spring.

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

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

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

@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 используется для автоматического введения зависимостей указанного типа в текущий компонент. В этом случае Хранилище дерева компонент вводится как зависимость от Контроллера дерева .

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

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

В качестве альтернативы вы могли бы вместо этого аннотировать каждый тип ответа аннотацией @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 вместо прямого аннотирования его @Компонентом .

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

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

Используя пример контроллера 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 , поскольку @RestController применяет ее на уровне класса.

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

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

Вывод

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

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

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