Para empezar con el desarrollo de servicios web RESTFul Java utilizaremos las utilidades que nos proporciona Netbeans para generar este tipo de servicios, en concreto el que nos permite generar los servicios RESTFul a partir de las entidades de persistencia de la base de datos, pero antes de entrar en materia, explicaremos que son este tipo de servicios web.
Un servicio web RESTful hace referencia a un servicio web que implementa la arquitectura REST, a continuación, haremos una breve introducción de estos servicios, esto es lo que veremos:
Creando servicios web RESTFul Java con PostgreSQL en Netbeans
- INTRODUCCIÓN A LOS SERVICIOS WEB RESTFUL
- SERVICIOS WEB RESTFUL JAVA (JAX-RS)
- CREAMOS LA BASE DE DATOS CUSTOMERDB EN POSTGRESQL
- DEFINIMOS LA CONEXIÓN A POSTGRESQL EN NETBEANS
- CREAMOS EL PROYECTO
- CREACIÓN DEL SERVICIO WEB RESTFUL DESDE LA BASE DE DATOS
- PROBAMOS NUESTRO DESARROLLO
- Documentación
Software utilizado
- Java
- Servicios web RESTful
- Netbeans IDE: es un software para facilitar el rápido desarrollo de aplicaciones de escritorio, móviles, y aplicaciones web.
- GlassFish: servidor de aplicaciones de software, en la instalación de Netbeans se puede incluir para integrarlo en nuestros desarrollos.
1. INTRODUCCIÓN A LOS SERVICIOS WEB RESTFUL
¿Qué es un servicio REST?
El significado de sus siglas es REpresentational State Transfer (REST) que según su definición clásica es un tipo de servicio con un estilo de arquitectura para sistemas distribuidos hipermedia como por ejemplo WWW. En definitiva es un protocolo que define una serie de reglas de comunicación entre componentes.
Para la arquitectura REST es el concepto de los recursos identificados por los identificadores de recursos universales (URI) que pueden ser manipulados usando una interfaz estándar, como HTTP, y por medio de representaciones de esos recursos se efectúa el intercambio de información.
Los servicios REST no son los únicos que se utilizan para implementar servicios web, otros por ejemplo son: SOA, RPC o WDSL, dependiendo del proyecto se utilizará una u otra herramienta, si bien el auge de los servicios RESTFul viene dado por su facilidad de comprensión e implementación, además de por ser una implementación más ligera y por su capacidad de transmitir datos directamente a través de HTTP.
Estas son las reglas básicas de la arquitectura REST que vienen incluidas en la implementación del protocolo HTTP:
- En primer lugar tendrá una arquitectura cliente servidor.
- Protocolo sin estado (stateless), el servidor no tiene porque mantener el estado del cliente.
- Es un sistema de capas e interfaz uniforme que garantiza al cliente su independencia.
- HTTP implementa la caché de las peticiones en la cabecera con Cache-control.
Servicios web RESTful
Así pues, teniendo claros estos conceptos y cómo se relacionan con el protocolo HTTP, y sabiendo que un servicio web RESTful hace referencia a un servicio web que implementa la arquitectura REST, podemos ya dar una definición más concisa, lo cual nos dejará claro cómo tenemos que implementarlo en nuestras aplicaciones. Un servicio web RESTful contiene lo siguiente:
- URI del recurso: como veremos después en nuestro ejemplo la URI: X nos indica el acceso al recurso a con el id 111
- Representaciones del recurso: los más comunes son JSON, XML y TXT, el que más se está utilizando es el formato JSON por su facilidad de acceso y presentación, así en nuestra cabecera se indicará, por ejemplo, el formato «Content-type: application/json», está información se utilizar desde el cliente para saber como es el tipo de respuesta y presentarla adecuadamente.
- Operaciones: HTTP define varios tipos de operaciones los más comunes GET, PUT, POST y DELETE. Una vez definidas en el servicio web, se traspasa la responsabilidad de utilizarlas adecuadamente al cliente.
- Hipervínculos: la respuesta puede incluir hipervínculos hacia otras acciones que podamos realizar sobre los recursos.
2. SERVICIOS WEB RESTFUL JAVA (JAX-RS)
Como indicábamos en el título vamos a utilizar Netbeans para la generación rápida de servicios web RESTFul. Para ello utiliza la implementación de referencia para JAX-RS con JSR 311 – Java API for RESTful Web Services (JAX-RS) and Jersey.
Como veremos en esta publicación el IDE nos proporciona test y la creación de aplicaciones cliente que acceden a los servicios web RESTFul, algunas de las características más importantes que nos proporciona son:
- Generación rápida de servicios web RESTful desde entidades JPA y patrones.
- Generación rápida de código para invocar a servicios como: Google Map, Yahoo News Search y StrikeIron.
- Generación de clientes RESTful Java.
- Generación de cliente para probar el código generado con los servicios web RESTful.
Las opciones de generación rápida nos permiten generar los servicios web RESTFul java a partir de las entidades de la base de datos, de la base de datos o de patrones, como puedes ver en la imagen:
Puede utilizar NetBeans IDE, ya sea para crear clases de entidad y los servicios web RESTful en el mismo proceso, o puede utilizar el IDE para crear servicios web RESTful de clases de entidades existentes. Vamos a utilizar los Servicios REST de asistente de base de datos para generar las clases de entidad y los servicios web RESTful en el mismo proceso, el asistente genera automáticamente la unidad de persistencia.
3. CREAMOS LA BASE DE DATOS CUSTOMERDB EN POSTGRESQL
Como indicábamos en el título de la publicación vamos a utilizar PostgreSQL como base de datos para crear nuestro servicio web RESTFul con Java, para ello veremos brevemente como hacer la instalación, explicaremos como es nuestra base de datos, y finalmente, crearemos la base de datos para después ejecutar los scrits de creación y población de datos, para centrarnos en el desarrollo con Netbeans.
Instalando PostgreSQL
La instalación de esta base de datos para pruebas es rápido y sencillo, si lo quieres instalar en Windows puedes descargar el instalador, si por el contrario utilizas linux como yo puedes ejecutar la instalación que suelen incluir estás bases de datos, ambas instalaciones incluirán PgAdmin que es un editor gráfico para nuestra base de datos.
Como te decía, para la instalación en Ubuntu simplemente ejecuta:
apt-get install postgresql-9.4
Dentro de mi tutorial de PostgreSQL (1) explico como preparar el entorno, aquí encontrarás más explicaciones sobre la instalación:
Definición de Customerdb
Para este desarrollo vamos a utilizar 3 tablas del proyecto Learning Project que consiste en un desarrollo sencillo para la administración de clientes para diferentes empresas y que utilizo como base para mis tutoriales, este es esquema de las entidades que lo forman:

Para este ejemplo nos centraremos en la tabla de países cb_country que como puedes ver en el esquema se relaciona con las tablas de idiomas (cb_language) y monedas (cb_currency), estas serán las tablas que seleccionaremos para la implementación de los servicios web RESTFul Java como veremos.
Creamos la base de datos
Creamos la base de datos desde la consola o desde la propia instalación de PgAdmin que hemos instalado con PostgreSQL, si la ejecutas desde consola este el código para la creación, ten en cuenta que yo utilizo mi usuario xulescode (lo tendrás que crear):
CREATE DATABASE customerdb WITH OWNER = xulescode ENCODING = 'UTF8' TABLESPACE = pg_default LC_COLLATE = 'es_ES.UTF-8' LC_CTYPE = 'es_ES.UTF-8' CONNECTION LIMIT = -1; GRANT ALL ON DATABASE customerdb TO xulescode; GRANT ALL ON DATABASE customerdb TO public;
Ahora vamos a continuar con la creación de las tablas desde Netbeans como veremos en el siguiente apartado, ejecutaremos dos scripts uno para la creación de las tablas y el segundo para poblarla.
4. DEFINIMOS LA CONEXIÓN A POSTGRESQL EN NETBEANS
Para empezar vamos crear una nueva conexión a una base de datos PostgreSQL desde Netbeans para ello seleccionamos la pestaña servicios y buscamos Database, si pulsamos se despliegan las conexiones que ya tienes por defecto.
Creamos una nueva conexión en Netbeans
Para crear una nueva nos colocamos sobre Database para abrir el menú popup de New Connection, se abrirá una ventana para la creación de la conexión donde seleccionamos la base de datos en este caso v, y una vez hecho esto rellenamos los parámetros básicos de la conexión: nombre de la base de datos, host, puerto y finalmente usuario y contraseña como se muestra en la imagen:
En el siguiente paso seleccionaremos el esquema base para nuestra conexión, es importante seleccionar el esquema donde crearemos las tablas para este proyecto, en nuestro caso seleccionaremos public como se puede ver en la imagen:
Con esto ya tenemos asociada la conexión con PostgreSQL a Netbeans, pulsamos fin y ya podemos acceder a la base de datos customerdb:
Creamos las tablas de la base de datos customerdb
Ahora ya estamos listos para ejecutar los scripts, empezaremos con el de la creación de las tablas con el que tendremos el esquema que presentábamos en el esquema de customerdb:
PostgreSQL SQL - Creación de las tablas
Para ejecutarlo desde Netbeans abrimos el editor SQL, abrimos el fichero descargado y lo ejecutamos directamente. Una vez finalizada la creación esta será la lista de tablas que se desplegará al seleccionar customerdb:
Poblaremos la base de datos siguiendo el mismo proceso, descarga el script y ejecútalo:
PostgreSQL Script SQL para poblar la base de datos Customerdb
Un ejemplo de la consulta sobre la tabla países (cb_country)que usaremos en la creación del servicio RESTFul:
5. CREAMOS EL PROYECTO
Vamos a utilizar un proyecto web de Netbeans para crearlo vamos a File > New Project al hacerlo nos aparecerá la primera ventana para dar nombre a nuestro proyecto como se muestra en la imagen:
A continuación, seleccionamos el servidor donde se ejecutará nuestro servicio:
Por último, nos aparece la opción de seleccionar la utilización de un framework en nuestro proyecto, para este ejemplo no necesitamos ninguno:
Ya tenemos listo nuestro proyecto.
6. CREACIÓN DEL SERVICIO WEB RESTFUL DESDE LA BASE DE DATOS
Desde el proyecto que hemos creado hacemos click con el botón derecho y seleccionamos New > Other > Web Services > RESTful Web Services from Database, a continuación, se abrirá el wizard para la creación paso a paso de los servicios web RESTFul de las tablas de la base de datos que seleccionemos, a continuación, la imagen si abres las opciones de los Web Services (servicios web):
Empezamos seleccionando la fuente de datos (datasource) que vamos a utilizar:
Como todavía no hemos definido una para la base de datos customerdb creamos una nueva seleccionando la opción New Datasource…:
Como se muestra en la imagen la nombramos como jdbc/customerdb y buscamos en el selector la conexión a la base de datos customerdb que ya tenemos definida:
Para este ejemplo seleccionaremos 3 tablas, seleccionando la tabla principal de países (cb_country) ya se añaden automáticamente las tablas relacionadas de idiomas (cb_language) y monedas (cb_currency) como se muestra en la imagen:
Una vez seleccionadas las tablas tenemos que definir el paquete donde se crearán las entidades:
Para finalizar seleccionamos el paquete donde creamos las clases para la generación de los servicios web:
Y listo, ya solo queda probarlo, una vez que el IDE finalice la generación de código podrás listar el proyecto y analizar las clases generadas en los paquetes de entidades y servicios, comprobarás que Java EE RESTful web services from a database instancia un EntityManager en cada clase una de las clases para los servicios web, esto elimina la necesidad del controlador JPA y genera un código más sencillo.
Compilamos para comprobar: posibles problemas y soluciones
En este punto tenemos que hacer un inciso, si has podido compilar y ejecutar el proyecto sin problemas desplegando una sencilla página web sobre Glassfish pasa al siguiente al 7. Probamos nuestro desarrollo.
Si todo fue bien esto es lo que verás:
Si falla al compilar y ejecutarlo, en tu consola aparece este mensaje:
Lo más probable es que tengamos que definir la conexión y el pool de conexiones a la base de datos directamente en el servidor veamos como.
Definiendo manualmente una conexión JDBC con su pool de conexiones en GlassFish
Hay un bug conocido en el que en algunas instalaciones falla la creación de la conexión a la base de datos en el servidor, y por eso la vamos a definir manualmente, te explico esto porque a mí ya me ha pasado.
En la estructura de nuestro directorio buscamos la carpeta Server Resources donde encontramos el fichero glassfish-resources.xml y que es donde se define la conexión y el pool de conexiones que vamos a utilizar en nuestra aplicación. Esta información se va a transmitir al servidor en el momento de desplegar el proyecto para que cree el Datasource y el pool de conexiones.
Este es su contenido:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd"> <resources> <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="org.postgresql.ds.PGSimpleDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="post-gre-sql_customerdb_xulescodePool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false"> <property name="serverName" value="192.168.0.14"/> <property name="portNumber" value="5432"/> <property name="databaseName" value="customerdb"/> <property name="User" value="xulescode"/> <property name="Password" value="xulescode"/> <property name="URL" value="jdbc:postgresql://192.168.0.14:5432/customerdb"/> <property name="driverClass" value="org.postgresql.Driver"/> </jdbc-connection-pool> <jdbc-resource enabled="true" jndi-name="jdbc/customerdbrest" object-type="user" pool-name="post-gre-sql_customerdb_xulescodePool"/> </resources>
En glassfish-resources.xml definimos el nombre jndi jndi-name y el nombre del pool pool-name, estos valores los podremos cambiar si queremos crear un pool nuevo directamente en nuestro servidor GlassFish.
La url para acceder a la instalación del servidorGlassFish será: http://localhost:4848/common/index.jsf, en la pestaña Resources está el apartado JDBC con los enlaces a JDBC Resources y JDBC Connection Pools como se muestra en la imagen:
Creamos el JDBC Connection Pool
Para crear el nuevo pool utiliza el botón New dentro de JDBC Connection Pools, donde te aparecerá la ventana de creación y podrás crearla con el nombre post-gre-sql_customerdb_xulescodePool u otro diferente si después actualizas el fichero glassfish-resources.xml, las opciones que tienes que seleccionar para crear el pool son : Pool Name: nombre-pool ; Resource Type: javax.sql.DataSource ; Datasource Class Name: org.postgresql.ds.PGSimpleDataSource; Database Driver Vendor: PostgreSQL.
Rellenamos las opciones generales de la base de datos, el nombre , la dirección del host de la conexión, el puerto, usuario y clave.
Creamos el JDBC Resource
Una vez creado el nuevo JDBC Connection Pool vamos a crear un nuevo JDBC Resource para utilizarlo en nuestra aplicación, para ello en el menú de la derecha en la pantalla de administración de GlassFish encontrarás la entrada de menú JDBC Resources, una vez abierta seleccionamos el botón New, nos aparece una ventana para introducir el nombre del JDBC Resource en mi caso jdbc/customerdb en el combo de selección del pool seleccionamos el que creamos anteriormente, introduce una descripción si lo crees conveniente y ya estamos listos para probar nuestro desarrollo.
7. PROBAMOS NUESTRO DESARROLLO
Ahora podemos crear un nuevo proyecto para generar una aplicación web cliente para probar el proyecto, en este caso para ver la funcionalidad lo vamos a crear dentro del propio proyecto.
Nos colocamos en el proyecto para desplegar el menú popup pulsando el botón derecho y seleccionamos Test RESTful Web Services, al hacerlo tenemos la opción de generar el cliente de pruebas en el proyecto o en otro proyecto web diferente como se muestra en la imagen seleccionamos Web Test Client in Project:
Al ejecutarlo se generará el fichero test-resbeans.html con una página web donde podremos probar los servicios REST creados, en la imagen la lista sobre los países (cb_country):
En este primer ejemplo utilizamos el recurso org.xulescode.entities.cbcountry/{from}/{to} que nos permite hacer un filtro por id desde un valor hasta otro valor.
A continuación, el ejemplo de pruebas de una consulta por id donde el recurso es org.xulescode.entities.cbcountry/{id}, al cual le añadimos la url http://localhost:8080/CustomerdbRest/webresources/ como puedes ver en la imagen:
Si copiamos directamente la URL en el navegador http://localhost:8080/CustomerdbRest/webresources/org.xulescode.entities.cbcountry/270 obtendremos el resultado en formato xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><cbCountry> <country>United States</country> <countrycode>US</countrycode> <description>United States of America</description> <displaysequence>@C@, @R@ @P@</displaysequence> <expressionphone>Y</expressionphone> <hasregion>89</hasregion> <ibancountry></ibancountry> <idcountry>270</idcountry> <idcurrency> <currency>Euro</currency> <cursymbol>E</cursymbol> <description>Euro</description> <idcurrency>7</idcurrency> <isactive>89</isactive> <isocode>EUR</isocode> <precisioncost>4</precisioncost> <precisionprize>4</precisionprize> <precisionstd>2</precisionstd> </idcurrency> <idlanguage> <countrycode>US</countrycode> <idlanguage>en_US</idlanguage> <isactive>89</isactive> <isbaselanguage>78</isbaselanguage> <issystemlanguage>78</issystemlanguage> <languageiso>en</languageiso> <namelanguage>English (USA)</namelanguage> </idlanguage> <isactive>true</isactive> <isdefault>89</isdefault> <regionname>State</regionname> </cbCountry>
Como puedes ver en las imágenes anteriores hay 5 tabs en la sección de salida de los Test:
- Tabular View: esta vista en plano muestra todas las direcciones URL.
- Raw View: muestra los datos devueltos por la petición que se mostrarán en formato XML o JSON dependiendo del tipo mime seleccionado: application/xml o application/json respectivamente.
- Sub-Resource: muestra las URLs de la fuente raíz (en base de datos la entidad relacionada con la tabla) y sus fuentes relacionadas (en base de datos las columnas).
- Headers: muestra la información de la cabecera HTTP.
- HTTP Monitor: muestra las peticiones actuales HTTP tanto enviadas como recibidas.
Documentación
- Servicios web RESTful con HTTP. Parte I: Introducción y bases téoricas
- Introducción a los servicios web RESTful
- Getting Started with RESTful Web Services: REpresentational State Transfer (REST) is an architectural style for distributed hypermedia systems, such as the World Wide Web. Central to the RESTful architecture is the concept of resources identified by universal resource identifiers (URIs). These resources can be manipulated using a standard interface, such as HTTP, and information is exchanged using representations of these resources. In this tutorial, you first learn a bit about REST and then you are shown how NetBeans IDE supports this architectural style.
- JSR 311: JAX-RS: The Java API for RESTful Web Services
- Jersey, the open source JAX-RS (JSR 311) Reference Implementation for building RESTful Web services
Espero que te haya sido útil, si es así compártelo en las redes sociales, gracias.
Muchas gracias, finalice el tutorial pero quedé con una duda, como hago por ejemplo si quiero hacer una consulta no por rango ni por id, si no por otro campo de la tabla por ejemplo el campo «nombre»
Gracias
Hola Julián.
Para hacer esto tienes que modificar el controlador CbCountryFacadeREST añadiendo la búsqueda que necesites, fíjate en las búsquedas por id y from/to , puedes ver por el path la url a la que van a llamar, crea unos métodos nuevos con el campo que te interese y listo, métodos del controlador inicial:
Espero que te sirva de ayuda.
Saludos.
Muy buen tuto, realice todos los pasos solo hasta el final me dio un problema cuando quiero buscar por id me aparece el siguiente error:
HTTP Status 500 – Internal Server Error
type Exception report
messageInternal Server Error
descriptionThe server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper
root cause
org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper
root cause
No logro entender el porque de este error.
Gracias
Hola Enrique.
Entiendo que tu problema es debido a que estás utilizando para la persistencia la librería de Eclipse, y está, no la tienes desplegada, por eso, en tu proyecto encuentra la clase, pero al desplegarla en el servidor te dice que no la encuentra.
Para resolver este problema primero haría funcionar el proyecto con las librerías que incluye Glassfish, y una vez te funcione, probaría con la librería de Eclipse.
Espero que te sirva de ayuda.
Saludos.
Hola muy interesante el tutorial me funcionan perfectamente, quisiera saber si tienen algun tutorial que me permitan consumir ese servicio en una aplicacion android?
Hola.
Muchas gracias por tu comentario, ahora mismo no tengo ningún tutorial de como consumir servicios RESTFul.
Me alegra mucho que te haya sido útil.
Saludos.
Hola cuando creo una consulta nueva me sale el error que el modulo no ha sido deployed? que debo hacer
Hola, la respuesta a tu pregunta la tienes en esta publicación, si te vas al apartado Compilamos para comprobar, puedes ver que describo el fallo que te da a ti, y a continuación tienes una explicación de como resolverlo que consiste en definir manualmente la conexión, ya que el problema es que no la encuentra y de ahí el error, la solución aquí: Definiendo manualmente una conexión JDBC con su pool de conexiones en GlassFish.
Muchas gracias por tu interés en mi publicación
Hola amigo tengo el problema de compilación pero estoy trabajando con wildfly 10. Tal vez me podrías ayudar con esto por favor. Muy bueno tu tutorial.
hola como puedo consumir los servicios res desde una página web en la misma aplicación
Gracias Julio por el tutorial se desplegó correctamente el proyecto pero al testearlo me arroja el mismo error que a Enrique:
HTTP Status 500 – Internal Server Error
type Exception report
messageInternal Server Error
descriptionThe server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper
En tu respuesta comentas:
«Para resolver este problema primero haría funcionar el proyecto con las librerías que incluye Glassfish, y una vez te funcione, probaría con la librería de Eclipse.»
Sin embargo no sé cómo configurar eso, ya entré a Propiedades del Proyecto y no veo dónde asignar esas librerías de Glassfish ( tampoco las de Eclipse), no sé si pudieras iluminarme por favor.
Un saludo
Hola buen día, tenes alguna aplicacion como ejemplo q le pegue a ese servicio restful?
Hola Ariel.
En este momento no tengo ninguna aplicación publicada que consuma los servicios.
Espero actualizar la web pronto y generar nuevos tutoriales que nos permitan ver como usar los servicios.
Saludos.
Excelente tutorial
Muchas gracias
Muchas gracias por tu valoración Diego.
Encantado de que te haya sido útil.
Saludos.
Gracias por el material de apoyo.
Tengo una consulta quizas este proyectando mal, pero si yo muevo un valor directo en la base de datos, hago un update a un campo de la tabla no desde un peticion PUT si no desde la misma interfaz del motor de la base de datos, porque cuando solicito un GET a la API REST no actualiza este cambio, y en caso de que se pueda, que tendria que cambiar.
gracias nuevamente
Hola Eduardo, muchas gracias por tu valoración.
Contestando a tu pregunta, lo único que se me ocurre es que el UPDATE no haya funcionado, después del UPDATE comprueba con un SELECT que los datos realmente se han actualizado.
Los datos que devuelve el GET de la API tienen que corresponderse exactamente con lo que hay en la base de datos, ya que no se está utilizando ningún sistema de caché.
Saludos.
Julio Yañez.