Параметры запроса
Почти каждому методу API нужны данные из запроса: номер записи из адреса, номер страницы, поле формы. В Jakarta REST их не нужно доставать из объекта запроса — достаточно объявить аргумент метода с нужной аннотацией, и сервер подставит значение, уже преобразованное в нужный тип.
Часть пути
Изменяемую часть адреса записывают в @Path в фигурных скобках, а в метод она приходит через @PathParam. Продолжаем файл src/main/java/com/example/blog/PostResource.java:
// src/main/java/com/example/blog/PostResource.java (фрагмент)
@GET
@Path("/{id}")
@Produces(MediaType.TEXT_PLAIN)
public String show(@PathParam("id") long id) {
return "Запись №" + id;
}
@GET
@Path("/{id}/comments/{commentId}")
@Produces(MediaType.TEXT_PLAIN)
public String comment(@PathParam("id") long id, @PathParam("commentId") long commentId) {
return "Комментарий " + commentId + " к записи " + id;
}Строка из адреса превращается в long автоматически. Вызовем оба метода:
curl http://localhost:8080/blog/api/posts/5
curl http://localhost:8080/blog/api/posts/5/comments/12Запись №5
Комментарий 12 к записи 5
Строка запроса
Параметры после ? читает @QueryParam. Если параметра может не быть, значение по умолчанию задаёт @DefaultValue:
// src/main/java/com/example/blog/PostResource.java (фрагмент)
@GET
@Produces(MediaType.TEXT_PLAIN)
public String list(@QueryParam("page") @DefaultValue("1") int page,
@QueryParam("tag") String tag) {
return "Записи, страница " + page + ", тег: " + tag;
}curl http://localhost:8080/blog/api/posts
curl "http://localhost:8080/blog/api/posts?page=2&tag=java"Записи, страница 1, тег: null
Записи, страница 2, тег: java
Без @DefaultValue отсутствующий параметр даёт null для объектов и 0 для чисел.
Заголовки и поля формы
// src/main/java/com/example/blog/PostResource.java (фрагмент)
@GET
@Path("/agent")
@Produces(MediaType.TEXT_PLAIN)
public String agent(@HeaderParam("User-Agent") String userAgent) {
return "Ваш клиент: " + userAgent;
}
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_PLAIN)
public String create(@FormParam("title") String title) {
return "Создана запись: " + title;
}@Consumes говорит, какой тип тела принимает метод: здесь это обычная HTML-форма.
curl http://localhost:8080/blog/api/posts/agent
curl -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" --data-urlencode "title=Привет" http://localhost:8080/blog/api/postsВаш клиент: curl/8.21.0
Создана запись: Привет
Обратите внимание на charset=UTF-8 в заголовке. Без него Open Liberty читает поля формы в кодировке ISO-8859-1, и ответ будет таким: Создана запись: ÐÑивеÑ.
Адрес /posts/agent подходит и под шаблон /{id}, но точный путь побеждает: Jakarta REST сначала выбирает метод с более конкретным @Path.
Сводка
| Аннотация | Откуда значение | Пример адреса |
|---|---|---|
@PathParam | Часть пути | /posts/5 |
@QueryParam | Строка запроса | /posts?page=2 |
@HeaderParam | Заголовок | User-Agent: curl |
@FormParam | Поле формы | title=Привет |
@CookieParam | Cookie | theme=dark |
@DefaultValue | Значение, если параметра нет | — |
Частая ошибка
Передать в путь значение, которое нельзя преобразовать в тип аргумента. Для /api/posts/abc строка abc не превращается в long, и сервер отвечает не ошибкой 400, а 404 Not Found с пустым телом — для Jakarta REST такой адрес просто не подходит под метод. Если нужен понятный ответ 400, принимайте String и проверяйте значение сами. В уроке о валидации появится ещё один способ — ограничения на параметрах.