Hasta ahora, el método con el que obteníamos los libros existentes en nuestro repositorio nos devolvía un JSON con todos los libros almacenados. Esto puede ser un problema si nuestro repositorio contiene demasiados libros, por lo que sería interesante poder realizar una paginación y ordenación de resultados.

Afortunadamente, Spring Framework cuenta con los mecanismos necesarios, no sólo para obtener resultados paginados, sino también para obtener dichos resultados ordenados en base a unos campos determinados.



Para ello, lo primero que tenemos que hacer es cambiar la clase de la que extiende nuestro repositorio. Ahora deberá extender de la clase PagingAndSortingRepository, que ofrece además de los métodos ya comentados, la posibilidad de realizar una paginación y ordenación de resultados.




Además, el fichero dispatcher-servlet.xml debe ser modificado para que el sistema MVC de Spring Framework sea capaz de interpretar las peticiones de paginación y ordenación de forma correcta. Para ello se añadirá a la configuración el bean PageableHandlerMethodArgumentResolver.



También cambiará la llamada de la clase LibroFacade. Ahora, el parámetro de entrada será un objeto de tipo Pageable y devolverá una página de libros Page<Libro>



Este cambio de parámetros debe también ser reflejado en el controlador LibroController que inicia el procesamiento de la llamada a nuestra API RESTful.



Una vez que hayamos configurado nuestra API RESTful, podremos realizar llamadas que requieran de paginación de la siguiente forma
GET /libros?page=0&size=1

Para realizar llamadas con ordenación serán de la siguiente forma
GET /libros?sort=titulo,asc

Estos parámetros de paginación y ordenación, pueden combinarse también. A continuación se muestra un ejemplo del resultado obtenido con una llamada de paginación y ordenación como la que sigue.

http://localhost:8080/spring.rest.jpa.ii/v1/libros?page=0&size=2&sort=titulo,asc

Este resultado contiene ciertos parámetros adicionales que informan del total de páginas de las que se dispone (totalPages), el total de elementos (totalElements) o si es la última página (last), además de devolver los libros que pertenecen a la página de resultados solicitada.


En esta ocasión hablaré del tratamiento de excepciones y de los códigos de respuesta de nuestra API RESTful. Si recordamos la primera versión de la API, no teníamos ningún mecanismo que informara al cliente de que un determinado recurso no existía. Si por ejemplo realizábamos la petición GET /libro/87, el servidor no devolvería ningún resultado, pero el código de respuesta sería 200 (OK).

Para este caso concreto, lo correcto sería devolver un código de respuesta 404 (Not found). Puedes encontrar más información sobre los diferentes tipos de códigos de respuesta aquí



Para proveer a nuestros servicios de los mecanismos de tratamiento de excepciones y generación de códigos de respuesta necesarios, hemos creado un nuevo paquete de nombre spring.rest.jpa.ii.exception en el que se han implementado dos clases.
  • ResourceNotFoundException: es la excepción que extiende de RuntimeException y que se lanzará cada vez que se pida un recurso inexistente. En el constructor, podemos pasar el identificador del recurso que se ha solicitado pero que no existe en base de datos.


  • RestExceptionController: es el controlador que gestionará las excepciones lanzadas en los controladores de nuestra API. Es por eso que se ha utilizado la anotación @ControllerAdvice en la línea 21. La clase dispone de un método llamado resourceNotFound que se invocará para gestionar la excepción lanzada. El método utiliza las siguientes anotaciones.
    • @ExceptionHandler: con esta anotación informamos del tipo de excepción que gestionará el método, en este caso ResourceNotFoundException
    • @ResponseStatus: indicamos el código de respuesta a devolver, en este caso un 404.
    • @ResponseBody: para incluir un mensaje informativo en referencia al recurso inexistente.


De esta forma, si realizamos la petición GET /libro/87, se devolverá un código de respuesta 404 indicando que el recurso no existe, además de un mensaje del tipo "El recurso [87] no ha sido encontrado".


Pulsa aquí para acceder al código de esta entrada en mi repositorio Github