JavaRush /Курсы /Модуль 5. Spring /Практика: создание REST-контроллера в Spring MVC

Практика: создание REST-контроллера в Spring MVC

Модуль 5. Spring
7 уровень , 5 лекция
Открыта

В предыдущих лекциях мы изучили основы Spring MVC: архитектуру, ключевые аннотации и базовые принципы маршрутизации. Теперь пора применить эти знания на практике и создать полноценный REST API.

Давайте разработаем контроллер для управления книгами в библиотеке. Наш API будет уметь получать список книг, находить книгу по ID, добавлять новые книги, обновлять информацию о них и удалять их из базы. В процессе мы создадим все необходимые CRUD-операции, научимся правильно обрабатывать HTTP-методы (GET, POST, PUT, DELETE), настроим возврат данных в формате JSON и добавим базовое тестирование.

REST API — это фундамент современной веб-разработки. Независимо от того, разрабатываете ли вы веб-приложение, мобильное приложение или микросервисную архитектуру, вам придется создавать и поддерживать API-endpoints. Давайте научимся делать это правильно!


1. Подготовка проекта

Зависимости. Для начала, убедимся, что наш Spring Boot проект настроен правильно. Включим в проект необходимые зависимости в файле pom.xml:


<dependencies>
  <!-- Spring Web для работы с MVC -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!-- Зависимость для работы с JSON -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
  </dependency>
</dependencies>

Ну а теперь приступаем к созданию контроллера.


2. Описание сущности Book

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


package com.example.demo.model;

public class Book {

    private Long id;
    private String title;
    private String author;

    // Конструкторы
    public Book() {}

    public Book(Long id, String title, String author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }

    // Геттеры и сеттеры
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

3. Создание REST-контроллера

Теперь мы готовы приступить к созданию нашего контроллера. Он будет обрабатывать HTTP-запросы для управления книгами. Используем аннотацию @RestController, чтобы указать Spring, что этот класс отвечает за обработку REST-запросов.


package com.example.demo.controller;

import com.example.demo.model.Book;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/books")
public class BookController {

    private final List<Book> books = new ArrayList<>();

    // Инициализация данных
    public BookController() {
        books.add(new Book(1L, "Clean Code", "Robert C. Martin"));
        books.add(new Book(2L, "Effective Java", "Joshua Bloch"));
    }

    // Получение всех книг
    @GetMapping
    public List<Book> getAllBooks() {
        return books;
    }

    // Получение книги по ID
    @GetMapping("/{id}")
    public Book getBookById(@PathVariable Long id) {
        return books.stream()
                .filter(book -> book.getId().equals(id))
                .findFirst()
                .orElseThrow(() -> new RuntimeException("Book not found"));
    }

    // Создание новой книги
    @PostMapping
    public Book createBook(@RequestBody Book book) {
        books.add(book);
        return book;
    }

    // Обновление книги
    @PutMapping("/{id}")
    public Book updateBook(@PathVariable Long id, @RequestBody Book updatedBook) {
        Book book = getBookById(id);
        book.setTitle(updatedBook.getTitle());
        book.setAuthor(updatedBook.getAuthor());
        return book;
    }

    // Удаление книги
    @DeleteMapping("/{id}")
    public void deleteBook(@PathVariable Long id) {
        Book book = getBookById(id);
        books.remove(book);
    }
}

4. Разбор кода контроллера

Основные методы контроллера

  • GET /books Возвращает список всех книг. Очень просто, использует метод books для возврата списка.
  • GET /books/{id} Находит книгу по ID. Если книга не найдена, выбрасывается исключение (можно улучшить обработку ошибок, но об этом позже).
  • POST /books Создает новую книгу. Мы передаем объект Book в теле запроса (аннотация @RequestBody).
  • PUT /books/{id} Обновляет существующую книгу по ID. Здесь мы сначала находим книгу по ID, а затем обновляем ее данные.
  • DELETE /books/{id} Удаляет книгу по ID. Сначала ищем книгу, затем удаляем из списка.

Параметры аннотаций

  • @RequestMapping("/books"): базовый путь для всех запросов.
  • @GetMapping, @PostMapping, @PutMapping, @DeleteMapping: обработка HTTP-запросов.
  • @PathVariable извлекает параметры из пути запроса.
  • @RequestBody читает тело запроса и преобразует его в объект Java.

5. Тестирование контроллера

Проверить работу API можно с помощью инструментов вроде Postman или обыкновенного cURL. Примеры запросов:

GET все книги


GET http://localhost:8080/books

GET книга по ID


GET http://localhost:8080/books

POST новая книга


POST http://localhost:8080/books
Content-Type: application/json

{
    "id": 3,
    "title": "The Pragmatic Programmer",
    "author": "Andrew Hunt"
}

DELETE удаление книги


DELETE http://localhost:8080/books/1

6. Типичные ошибки и их устранение

  1. Ошибка 404 Not Found при GET /books/{id} Это происходит, если искомая книга отсутствует в списке. Убедитесь, что books инициализирован правильно.
  2. Ошибка в сериализации JSON Проверьте, что все поля объектов имеют геттеры/сеттеры, иначе Jackson не сможет преобразовать объект в JSON.
  3. Ошибка 415 Unsupported Media Type при POST или PUT запросах Убедитесь, что заголовок запроса содержит Content-Type: application/json.

Теперь у нас есть полностью функциональный REST-контроллер! В следующей лекции мы познакомимся с шаблонизатором Thymeleaf, чтобы научиться создавать красивые HTML-страницы для наших веб-приложений.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ