Коды ответа и Response
Код ответа — первое, что видит клиент API: получилось или нет, создана ли запись, существует ли она. Если метод ресурса возвращает объект, Jakarta REST отвечает 200 OK. Когда нужен другой код или дополнительные заголовки, метод возвращает объект Response — полное описание ответа: статус, заголовки и тело.
Основные коды
| Код | Когда используют |
|---|---|
200 OK | Данные получены |
201 Created | Запись создана, адрес — в заголовке Location |
204 No Content | Успех, тела нет: например, после удаления |
400 Bad Request | Ошибка в данных клиента |
404 Not Found | Записи нет |
415 Unsupported Media Type | Неподходящий Content-Type |
500 Internal Server Error | Необработанное исключение на сервере |
Запись или 404
Добавьте в PostStore метод удаления, который сообщает, была ли запись:
// src/main/java/com/example/blog/PostStore.java (фрагмент)
public boolean delete(long id) {
return posts.remove(id) != null;
}Теперь методы ресурса src/main/java/com/example/blog/PostResource.java:
// src/main/java/com/example/blog/PostResource.java (фрагмент)
@GET
@Path("/{id}")
public Response show(@PathParam("id") long id) {
return store.findById(id)
.map(post -> Response.ok(post).build())
.orElse(Response.status(Response.Status.NOT_FOUND).build());
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response create(NewPost data, @Context UriInfo uriInfo) {
Post post = store.add(data);
URI location = uriInfo.getAbsolutePathBuilder()
.path(String.valueOf(post.id()))
.build();
return Response.created(location).entity(post).build();
}
@DELETE
@Path("/{id}")
public void delete(@PathParam("id") long id) {
if (!store.delete(id)) {
throw new NotFoundException("Запись " + id + " не найдена");
}
}Для импортов понадобятся jakarta.ws.rs.DELETE, jakarta.ws.rs.NotFoundException, jakarta.ws.rs.core.Context, jakarta.ws.rs.core.Response, jakarta.ws.rs.core.UriInfo и java.net.URI.
Что здесь происходит:
showвозвращаетResponse.ok(post)или ответ с кодом 404 без тела.createстроит адрес новой записи из адреса текущего запроса.UriInfoсервер передаёт через@Context.Response.created(location)даёт код 201 и заголовокLocation.deleteничего не возвращает — для методаvoidJakarta REST отвечает 204. ИсключениеNotFoundExceptionпревращается в ответ 404.
Проверка
curl -i -H "Content-Type: application/json" -d '{"title":"Коды ответа","body":"201, 204 и 404."}' http://localhost:8080/blog/api/postsHTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:8080/blog/api/posts/3
{"body":"201, 204 и 404.","createdAt":"2026-10-04","id":3,"title":"Коды ответа"}
curl -i -X DELETE http://localhost:8080/blog/api/posts/3
curl -i -X DELETE http://localhost:8080/blog/api/posts/3
curl -i http://localhost:8080/blog/api/posts/99Первое удаление вернёт HTTP/1.1 204 No Content, второе — HTTP/1.1 404 Not Found: записи уже нет. Запрос несуществующей записи тоже даст 404.
Готовые исключения
Вместо Response можно бросить исключение — Jakarta REST сам превратит его в код ответа:
| Исключение | Код |
|---|---|
BadRequestException | 400 |
NotAuthorizedException | 401 |
ForbiddenException | 403 |
NotFoundException | 404 |
WebApplicationException(status) | Любой |
Частая ошибка
Вернуть null из метода, который должен отдавать объект. В прошлом уроке show возвращал store.findById(id).orElse(null), и запрос несуществующей записи заканчивался так:
HTTP/1.1 204 No Content
Клиент видит успех и пустое тело вместо ошибки. Если записи нет, отвечайте 404 — через Response или исключение.