JavaRush /Курсы /Модуль 5. Spring /Обработка параметров и тела запроса (Query Parameters, Pa...

Обработка параметров и тела запроса (Query Parameters, Path Variables)

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

Когда сервер предоставляет API, параметры и данные запросов играют ключевую роль в управлении ресурсами. Сегодня мы разберем:

  1. Обработку Query Parameters: фильтры и сортировку.
  2. Работу с Path Variables: динамические сегменты URI.
  3. Как обрабатывать ошибки, связанные с параметрами.

И, конечно же, напишем код! Потому что теория без практики — словно метод без реализации.


Что такое Query Parameters?

Начнем с Query Parameters. Это параметры, которые передаются клиентом в строке запроса после символа ?. Они используются для фильтрации, сортировки, поиска данных и других уточнений запроса.

Пример URL с Query Parameters:


https://api.myapp.com/products?category=electronics&sort=price&order=asc
  • category=electronics: указывает фильтр по категории "электроника".
  • sort=price: сигнализирует, что мы сортируем по цене.
  • order=asc: добавляет уточнение, что сортировка восходящая.

Аннотация @RequestParam

Для того чтобы обработать Query Parameters в Spring, используется аннотация @RequestParam. Давайте посмотрим на пример кода:


@RestController
@RequestMapping("/products")
public class ProductController {

    @GetMapping
    public List<Product> getProducts(
            @RequestParam(required = false) String category,
            @RequestParam(defaultValue = "name") String sort,
            @RequestParam(defaultValue = "asc") String order
    ) {
        // Логика фильтрации, сортировки
        return productService.getProducts(category, sort, order);
    }
}
  • @RequestParam(required = false): параметр не обязателен. Если клиент не передаст category, он будет равен null.
  • defaultValue: задает значение по умолчанию, если параметр отсутствует в запросе.

Когда запрос отправляется на /products?category=clothing, в методе getProducts переменная category будет иметь значение "clothing", а sort и order примут значения по умолчанию.


Что такое Path Variables?

Path Variables (переменные пути) — это части URI, которые включают динамические значения.

Представьте, что у нас есть REST API для управления товарами, и нам нужно получить товар по его ID. Вот пример URI:


https://api.myapp.com/products/42

Здесь 42 — это идентификатор товара, и мы хотим извлечь его из пути. Для этого используется аннотация @PathVariable.

Аннотация @PathVariable

Spring позволяет "выцарапывать" эти значения из URI следующим образом:


@RestController
@RequestMapping("/products")
public class ProductController {

    @GetMapping("/{id}")
    public Product getProductById(@PathVariable Long id) {
        // Логика получения продукта по ID
        return productService.getProductById(id);
    }
}

Когда клиент отправит запрос GET /products/42, переменная id получит значение 42.


Объединяем @RequestParam и @PathVariable

А теперь, как говорят программисты, идём на уровень выше. Мы можем совмещать их вместе! Например, можно сделать следующую комбинацию:

  • URI содержит динамическое значение (id), чтобы идентифицировать ресурс.
  • Query Parameters используются для дополнительной настройки.

Пример: получение заказов пользователя с фильтром


@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{userId}/orders")
    public List<Order> getUserOrders(
            @PathVariable Long userId,
            @RequestParam(required = false) String status,
            @RequestParam(defaultValue = "date") String sort
    ) {
        // Логика фильтрации заказов пользователя
        return orderService.getUserOrders(userId, status, sort);
    }
}

Запрос:


GET /users/101/orders?status=completed&sort=price

В этом примере:

  • userId будет равен 101.
  • status будет равен "completed".
  • sort будет равен "price".

Валидируем параметры запроса

Не всегда клиенты будут отправлять нам корректные данные. апример, что делать, если в запросе указан ID пользователя как abc, а это явно некорректно?

Обработка ошибок

Spring автоматически вернет ошибку, если @PathVariable или @RequestParam не соответствует ожидаемому типу. Например:


@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
    return productService.getProductById(id);
}

Запрос GET /products/abc вызовет:


HTTP 400 Bad Request

Чтобы сделать обработку ошибок более изящной, можно использовать аннотацию @ExceptionHandler:


@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public ResponseEntity<String> handleTypeMismatch(MethodArgumentTypeMismatchException ex) {
        return ResponseEntity
                .badRequest()
                .body("Invalid parameter: " + ex.getName());
    }
}

Теперь ошибка будет более дружелюбной для клиента:


HTTP 400 Bad Request
Body: Invalid parameter: id

Практика: Пример REST API для работы с книгами

Давайте создадим REST API для работы с книгами. API позволит:

  1. Получать книгу по ID.
  2. Искать книги по жанру с сортировкой.

Класс сущности Book


@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;
    private String genre;
    private double price;

    // Геттеры и сеттеры
}

Репозиторий BookRepository


@Repository
public interface BookRepository extends JpaRepository<Book, Long> {

    List<Book> findByGenre(String genre, Sort sort);
}

Сервис BookService


@Service
public class BookService {

    @Autowired
    private BookRepository bookRepository;

    public Book getBookById(Long id) {
        return bookRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Book not found!"));
    }

    public List<Book> getBooksByGenre(String genre, String sortField) {
        Sort sort = Sort.by(Sort.Direction.ASC, sortField);
        return bookRepository.findByGenre(genre, sort);
    }
}

Контроллер BookController


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

    @Autowired
    private BookService bookService;

    @GetMapping("/{id}")
    public Book getBookById(@PathVariable Long id) {
        return bookService.getBookById(id);
    }

    @GetMapping
    public List<Book> getBooksByGenre(
            @RequestParam(required = false) String genre,
            @RequestParam(defaultValue = "title") String sort
    ) {
        return bookService.getBooksByGenre(genre, sort);
    }
}

Теперь:

  • GET /books/1 вернет книгу с ID 1.
  • GET /books?genre=fantasy&sort=price вернет все книги жанра "fantasy", отсортированные по цене.

Типичные ошибки и их решение

  1. @PathVariable отсутствует в URI. Убедитесь, что переменная пути указана в маршруте (например, /{id}).
  2. Неправильный тип данных параметра. Если id ожидает Long, а клиент передал строку, будет ошибка 400.
  3. Отсутствие обязательных Query Parameters. Убедитесь, что вы используете required = false, если параметр необязателен.

На этом этапе вы освоили работу с Query Parameters и Path Variables. Теперь ваши REST API станут более функциональными и гибкими. Держите курс на следующее занятие и не забывайте тестировать API!

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