solucionar solucion not found error como java rest jax-rs http-status-codes jersey-2.0

java - solucion - ¿Es correcto devolver 404 cuando no se encuentra un recurso REST?



http status 404-not found netbeans (3)

Sí, es bastante común devolver 404 para un recurso que no se encuentra. Al igual que una página web, cuando no se encuentra, obtienes un 404. No es solo REST, sino un estándar HTTP.

Cada recurso debe tener una ubicación URL. Las URLs no necesitan ser estáticas, pueden estar templated . Por lo tanto, es posible que la URL real solicitada no tenga un recurso. Es deber del servidor desglosar la URL de la plantilla para buscar el recurso. Si el recurso no existe, entonces es "No encontrado"

Aquí está de la especificación de HTTP 1.1

404 No encontrado

El servidor no ha encontrado nada que coincida con el URI de solicitud. No se da ninguna indicación de si la condición es temporal o permanente. El código de estado 410 (Desaparecido) DEBERÍA usarse si el servidor sabe, a través de algún mecanismo configurable internamente, que un recurso antiguo no está disponible permanentemente y no tiene una dirección de reenvío. Este código de estado se usa comúnmente cuando el servidor no desea revelar exactamente por qué se rechazó la solicitud o cuando no se aplica ninguna otra respuesta.

Aquí está para 204

204 Sin contenido

El servidor ha cumplido con la solicitud pero no necesita devolver un cuerpo de entidad, y puede querer devolver información actualizada. La respuesta PUEDE incluir metainformación nueva o actualizada en forma de encabezados de entidad, que si están presentes DEBEN asociarse con la variante solicitada.

Si el cliente es un agente de usuario, NO DEBE cambiar su vista de documento desde la que causó el envío de la solicitud. Esta respuesta está destinada principalmente a permitir que se realicen acciones para que se realicen acciones sin que se produzca un cambio en la vista de documento activo del agente de usuario, aunque cualquier información nueva o actualizada DEBE aplicarse al documento que se encuentra actualmente en la vista activa del agente de usuario.

La respuesta 204 NO DEBE incluir un cuerpo de mensaje y, por lo tanto, siempre termina con la primera línea vacía después de los campos de encabezado.

Normalmente se usaría 204 cuando se haya actualizado o creado una representación y no haya necesidad de enviar un cuerpo de respuesta. En el caso de un POST, puede enviar solo la ubicación del recurso recién creado. Algo como

@POST @Path("/something") @Consumes(...) public Response createBuzz(Domain domain, @Context UriInfo uriInfo) { int domainId = // create domain and get created id UriBuilder builder = uriInfo.getAbsolutePathBuilder(); builder.path(Integer.toString(domainId)); // concatenate the id. return Response.created(builder.build()).build(); }

El created(URI) enviará de vuelta la respuesta con el URI recién creado en el encabezado Location .

Añadiendo a la primera parte. Solo debe tener en cuenta que cada solicitud de un cliente es una solicitud para acceder a un recurso, ya sea solo para obtenerlo o actualizarlo con PUT. Y un recurso puede ser cualquier cosa en el servidor. Si el recurso no existe, entonces una respuesta general sería decirle al cliente que no podemos encontrar ese recurso.

Para ampliar su ejemplo. Digamos que FooService encarga de la base de datos. Cada fila en la base de datos puede considerarse un recurso. Y cada una de esas filas (recursos) tiene una URL única, como foo/db/1 podría ubicar una fila con una clave principal 1. Si no se puede encontrar el ID, ese recurso es "No encontrado"

Digamos que tengo un recurso simple de REST de Jersey como sigue:

@Path("/foos") public class MyRestlet extends BaseRestlet { @GET @Path("/{fooId}") @Produces(MediaType.APPLICATION_XML) public Response getFoo(@PathParam("fooId") final String fooId) throws IOException, ParseException { final Foo foo = fooService.getFoo(fooId); if (foo != null) { return Response.status(Response.Status.OK).entity(foo).build(); } else { return Response.status(Response.Status.NOT_FOUND).build(); } } }

Basado en el código anterior, ¿es correcto devolver un estado NOT_FOUND ( 404 ), o debo devolver 204 , o algún otro código más apropiado?

¡Muchas gracias de antemano!


Un código de error 4XX significa error del lado del cliente.
Cuando solicita un recurso estático como una imagen o una página html, devolver una respuesta 404 tiene sentido como:

El código de respuesta de error del cliente HTTP 404 No encontrado indica que el servidor no puede encontrar el recurso solicitado. Los enlaces que conducen a una página 404 a menudo se llaman enlaces rotos o muertos, y pueden estar sujetos a la podredumbre del enlace.

A medida que proporciona a los clientes algunos métodos REST, confía en los métodos HTTP, pero no debe considerar los servicios REST como recursos simples.
Para los clientes, una respuesta de error en el método REST a menudo se maneja cerca de los errores de otros procesos.

Por ejemplo, para detectar errores durante las invocaciones de REST o en otro lugar, los clientes podrían usar catchError() de RxJS .

Podríamos escribir un código (en TypeScript / Angular 2 para el código de ejemplo) de esta manera para delegar el procesamiento del error a una función:

return this.http .get<Foo>("/api/foos") .pipe( catchError(this.handleError) ) .map(foo => {...})

El problema es que cualquier error de HTTP (5XX o 4XXX) terminará en la devolución de llamada catchError() .
Realmente puede hacer que las respuestas de la API REST sean confusas para los clientes.

Si hacemos un paralelo con el lenguaje de programación, podríamos considerar 5XX / 4XX como flujo de excepción.
En general, no lanzamos una excepción solo porque no se encuentran los datos, los lanzamos como no se encuentran los datos y que se habrían encontrado esos datos .
Para la API REST, debemos seguir la misma lógica.

Si no se puede encontrar la entidad, devolver OK en los dos casos es perfectamente OK :

@GET @Path("/{fooId}") @Produces(MediaType.APPLICATION_XML) public Response getFoo(@PathParam("fooId") final String fooId) throws IOException, ParseException { final Foo foo = fooService.getFoo(fooId); if (foo != null){ return Response.status(Response.Status.OK).entity(foo).build(); } return Response.status(Response.Status.OK).build(); }

El cliente podría manejar el resultado de acuerdo con el resultado presente o faltante.
No creo que devolver 204 aporte algún valor útil.
La documentación HTTP 204 establece que:

El cliente no necesita alejarse de su página actual.

Sin embargo, solicitar un recurso REST y, más en particular, mediante un método GET no significa que el cliente esté a punto de terminar un flujo de trabajo (eso tiene más sentido con los métodos POST / PUT).

El documento agrega también:

El caso de uso común es devolver 204 como resultado de una solicitud PUT, actualizar un recurso, sin cambiar el contenido actual de la página que se muestra al usuario.

Realmente no estamos en este caso.

Algunos códigos HTTP específicos para el emparejamiento clásico de navegación combinan finamente con los códigos de retorno de la API REST (201, 202, 401, etc.), pero no siempre es así. Así que para estos casos, en lugar de torcer los códigos originales, preferiría que sean sencillos utilizando códigos más generales: 200 , 400 .


Una respuesta 404 en este caso es bastante típica y fácil de consumir para los usuarios de API.

Un problema es que es difícil para un cliente saber si obtuvo un 404 debido a que no se encontró la entidad en particular, o debido a un problema estructural en el URI. En su ejemplo, /foos/5 podría devolver 404 porque el foo con id = 5 no existe. Sin embargo, /food/1 devolvería 404 incluso si foo con id=1 existe (porque foos está mal escrito). En otras palabras, 404 significa un URI mal construido o una referencia a un recurso inexistente.

Otro problema surge cuando tiene un URI que hace referencia a múltiples recursos. Con una respuesta 404 simple, el cliente no tiene idea de cuál de los recursos de referencia no se encontró.

Ambos de estos problemas se pueden mitigar parcialmente devolviendo información adicional en el cuerpo de respuesta para que la persona que llama sepa exactamente lo que no se encontró.