Адреса, параметры пути и строки запроса
Одного адреса со списком мало: нужно открыть конкретную статью и отфильтровать список. Номер статьи обычно передают частью пути — /api/posts/2, а необязательные условия — в строке запроса после ?: /api/posts?author=anna. Spring умеет доставать оба вида параметров прямо в аргументы метода.
Общий префикс
Чтобы не повторять /api/posts в каждом методе, адрес ставят над классом:
// src/main/java/com/example/blog/PostController.java
@RestController
@RequestMapping("/api/posts")
public class PostController {
private final PostService postService;
public PostController(PostService postService) {
this.postService = postService;
}
@GetMapping
public List<Post> list() {
return postService.findAll();
}
}@RequestMapping("/api/posts") задаёт префикс для всех методов класса, а пустой @GetMapping означает сам префикс, то есть GET /api/posts.
Параметр пути
// src/main/java/com/example/blog/PostController.java
@GetMapping("/{id}")
public Post show(@PathVariable Long id) {
return postService.findById(id);
}Фигурные скобки в адресе объявляют переменную часть. @PathVariable кладёт её значение в аргумент с тем же именем и сам переводит текст "2" в число Long. В сервисе добавим поиск по номеру:
// src/main/java/com/example/blog/PostService.java
public Post findById(Long id) {
return repository.findById(id)
.orElseThrow(() -> new PostNotFoundException(id));
}// src/main/java/com/example/blog/PostNotFoundException.java
package com.example.blog;
public class PostNotFoundException extends RuntimeException {
public PostNotFoundException(Long id) {
super("Статья " + id + " не найдена");
}
}Запрос curl http://localhost:8080/api/posts/2 вернёт статью номер 2. Для несуществующего номера пока придёт ошибка 500 — в уроке об обработке ошибок превратим её в понятный ответ 404.
Параметр строки запроса
// src/main/java/com/example/blog/PostController.java
@GetMapping
public List<Post> list(@RequestParam(required = false) String author) {
return postService.findAll(author);
}// src/main/java/com/example/blog/PostService.java
public List<Post> findAll(String author) {
return repository.findAll().stream()
.filter(post -> author == null || post.author().equals(author))
.sorted(Comparator.comparing(Post::id))
.limit(properties.pageSize())
.toList();
}@RequestParam берёт значение author из строки запроса. Без required = false параметр был бы обязательным. Когда статьи появятся, запрос curl "http://localhost:8080/api/posts?author=anna" вернёт только статьи Анны:
[{"id":1,"title":"Привет, Spring","body":"Первая статья","author":"anna","createdAt":"2026-10-04T08:50:07.494425300Z"}]Адрес в кавычках, потому что знак ? и & командная оболочка может понять по-своему.
Значение по умолчанию
@RequestParam(defaultValue = "0") int pageЕсли параметра нет, Spring подставит 0. Такой параметр уже необязателен.
Аннотации для методов HTTP
| Аннотация | Запрос | Назначение |
|---|---|---|
@GetMapping | GET | Получить данные |
@PostMapping | POST | Создать |
@PutMapping | PUT | Заменить целиком |
@PatchMapping | PATCH | Изменить часть |
@DeleteMapping | DELETE | Удалить |
Частая ошибка
Если в путь вместо числа попал текст, например /api/posts/abc, Spring не сможет перевести его в Long и ответит 400:
{"timestamp":"2026-10-04T08:50:07.919Z","status":400,"error":"Bad Request","path":"/api/posts/abc"}В журнале появится Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'. Это не ошибка в коде — клиент прислал неверный адрес.