Vamos a explicar cómo crear servicios REST que trabajen con JSON en una aplicación web Java.
Los servicios REST que devuelven JSON son cada vez más utilizados, porque se adaptan muy bien a las necesidades de los nuevos frameworks JavaScript, tanto para aplicaciones web (Angular, React,…) como para aplicaciones móviles híbridas (Ionic).
Las herramientas que debemos tener instaladas en nuestro equipo para el ejemplo son:
Debemos tener también nuestra aplicación web Java creada. Si no es así, puedes ver como crearla de forma sencilla en esta página: http://www.infointernet.es/internet-avanzado/java/crear-una-aplicacion-web-java-eclipse-maven/.
Existen dos alternativas principales a la hora de crear los servicios REST en Java:
- Con Spring MVC: útil si ya utilizamos este framework en nuestro proyecto o estamos muy habituados a él.
- Con JAX-RS: es la especificación de Java para la creación de servicios REST. Esta será la opción que utilicemos en esta entrada, al ser la más simple y estándar.
Como hemos comentado anteriormente JAX-RS es una especificación, por lo que debemos utilizar alguna libería que lo implemente: RESTEasy (integrado en WildFly), Jersey (integrado en Glassfish), etc.
En nuestro ejemplo optaremos por Jersey, que es la de uso más extendido. Además, le añadiremos un módulo para trabajar con JSON llamado Jackson.
Paso 1: Añadir dependencias
Una vez tenemos nuestro proyecto Java gestionado con Maven, le añadiremos las dos siguientes dependencias:
<dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>2.25.1</version> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.25.1</version> </dependency>
Paso 2: Crear los beans
En nuestro ejemplo crearemos dos beans, uno para las películas y otro para los actores:
public class Actor { private String nombre; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } } public class Pelicula { private String titulo; private List actoresList; public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } public List getActoresList() { return actoresList; } public void setActoresList(List actoresList) { this.actoresList = actoresList; } }
Paso 3: Crear la aplicación JAX-RS y desplegarla en el servidor
JAX-RS proporciona una clase abstracta agnóstica de despliegue llamada Application que nos permitirá definir el paquete raíz donde están los servicios (recursos) REST así como como los provider. En nuestro caso, crearemos una clase que extiende ResourceConfig, que a su vez extiende a la clase Application.
@ApplicationPath("rest") public class Application extends ResourceConfig { public Application() { // Paquete donde están nuestros servicios REST packages("es.infointernet.rest"); // Registramos el Provider de JSON de Jackson register(JacksonFeature.class); } }
Con la anotación @ApplicationPath estamos registrando nuestra aplicación en el servidor, además de indicar que estará escuchando en el path “rest”. También podríamos registrarla como un servlet, pero no vamos a complicar el ejemplo.
Paso 4: Crear los servicios
Ahora ya solo nos quedaría crear las clases para los recursos, donde indicaremos las URL y parámetros que recibirán. Veamos un ejemplo:
@Path("/pelicula") public class PeliculaResource { @GET @Path("{idPelicula}") @Produces({MediaType.APPLICATION_JSON+";charset=utf-8"}) public Pelicula getPelicula(@PathParam("idPelicula") Integer idPelicula) throws Exception{ //Habría que llamar a un servicio que devolviera la película con el id pasado como parámetro return getPeliculaEjemplo(); } @GET @Produces({MediaType.APPLICATION_JSON+";charset=utf-8"}) public Pelicula findPeliculas(@QueryParam("titulo") String titulo, @QueryParam("nombreActor") String nombreActor) throws Exception{ // Habría que llamar a un servicio de búsqueda de películas return getPeliculaEjemplo(); } /** * Servicio de ejemplo. * @return */ private Pelicula getPeliculaEjemplo(){ List actores = new ArrayList(); Actor a = new Actor(); a.setNombre("Penélope Cruz"); actores.add(a); Pelicula p = new Pelicula(); p.setTitulo("Jamón Jamón"); p.setActoresList(actores); return p; } }
Vamos a explicar un poco las anotaciones:
- @Path: Nos sirve para especificar la URL donde van a estar publicados nuestros servicios. Se puede aplicar a una clase y/o a un método. Puede recibir valores entre llaves que corresponderían a parámetros ( @Path(“{idPelicula}”))
- @GET: Indica que a ese método hay que invocarlo por el método HTTP GET. Se suelen utilizar:
- GET: Para recuperar recursos
- POST: Para añadir recursos
- PUT: Para modificar recursos
- DELETE: Para borrar recursos
- @Produces({MediaType.APPLICATION_JSON+”;charset=utf-8″}): Con esto indicamos que el método devuelve JSON codificado en UTF-8. Es importante la codificación, para que los caracteres acentuados en español se devuelvan correctamente.
- @PathParam: Se utiliza para mapear los parámetros pasados por el path de la URL
- @QueryParam: Se utiliza para mapear los parámetros pasados por la URL
Para invocar a los métodos anteriores deberíamos poner, por ejemplo:
- Primer método: http://localhost:8080/<nombe_aplicacion>/rest/pelicula/125
- Segundo método: http://localhost:8080/<nombe_aplicacion>/rest/pelicula?titulo=jamón
Existen muchas más anotaciones que ofrecen muchas más posibilidades, pero se salen del objetivo del ejemplo. Si quieres profundizar más, puedes ver algunos ejemplos aquí: https://jersey.java.net/documentation/latest/jaxrs-resources.html
Espero que te haya sido de utilidad este artículo. Si tienes cualquier duda o comentario no dudes en escribirme.
Puedes descargar el código del ejemplo aquí: DemoRest. También puedes descargar el ejemplo completo, con seguridad incluida, de: https://github.com/mpecero/jaxrs-jwt-example
En próximos artículos explicaré como securizar estos servicios.
Nice post. I was checking continuously this blog and
I’m impressed! Extremely useful information specifically the
last part 🙂 I care for such information much.
I was looking for this certain information for a long time.
Thank you and good luck.
Thank yout for your comment
Muchas gracias, está bien explicado y me ha sido de gran ayuda! 😀
Muy buena información en este blog, me gustaría haber visto esto antes.