Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Коды ответа и 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 ничего не возвращает — для метода void Jakarta REST отвечает 204. Исключение NotFoundException превращается в ответ 404.

Проверка

curl -i -H "Content-Type: application/json" -d '{"title":"Коды ответа","body":"201, 204 и 404."}' http://localhost:8080/blog/api/posts
HTTP/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 сам превратит его в код ответа:

ИсключениеКод
BadRequestException400
NotAuthorizedException401
ForbiddenException403
NotFoundException404
WebApplicationException(status)Любой

Частая ошибка

Вернуть null из метода, который должен отдавать объект. В прошлом уроке show возвращал store.findById(id).orElse(null), и запрос несуществующей записи заканчивался так:

HTTP/1.1 204 No Content

Клиент видит успех и пустое тело вместо ошибки. Если записи нет, отвечайте 404 — через Response или исключение.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.