Serveis web RESTful amb Java EE7. Escrivint serveis web

Explicarem, mitjançant exemples, els conceptes més rellevants dels serveis web RESTful (de l’anglès REpresentational State Transfer), aprendreu a crear-ne i a fer-ne el desplegament mitjançant exemples.

REST no és un protocol, sinó un conjunt de regles i principis que permeten desenvolupar serveis web fent servir HTTP com a protocol de comunicacions entre el client i el servei web, i es basa a definir accions sobre recursos mitjançant l’ús dels mètodes GET, POST, PUT i DELETE inherents d’HTTP.

Per a REST, qualsevol cosa que es pugui identificar amb un URI (de l’anglès Uniform Resource Identifier) es considera un recurs, i, per tant, es pot manipular mitjançant accions (també anomenades verbs) especificades a la capçalera HTTP de les peticions seguint el següent conjunt de regles i principis que regeixen REST:

  • POST: crea un recurs nou.
  • GET: consulta el recurs i n’obté la representació.
  • DELETE: esborra un recurs.
  • PUT: modifica un recurs.
  • HEAD: obté metainformació del recurs.

REST es basa en l’ús d’estàndards oberts en totes les seves parts; així, fa servir URI per a la localització de recursos, HTTP com a protocol de transport, els verbs HTTP per especificar les accions sobre els recursos i els tipus MIME per a la representació dels recursos (XML, JSON, XHTML, HTML, PDF, GIF, JPG, PNG, etc.).

Format JSON

JSON (de l’anglès Java Script Object Notation) és un format lleuger d’intercanvi de dades. És fàcil de llegir i escriure per als éssers humans i, per a les màquines, d’analitzar i generar. Això el fa ideal per representar els recursos en arquitectures REST. Un dels principals problemes dels serveis web basats en SOAP és la mida dels missatges d’intercanvi; l’ús de JSON permet minimitzar la informació a enviar.

En una comparació ràpida entre REST i SOAP veiem que REST fa servir gairebé sempre HTTP com a mecanisme de comunicació i XML o JSON per intercanviar dades. Un servei REST no té estat i cada URI representa un recurs sobre el qual s’opera amb verbs HTTP. Un servei web REST no requereix de missatges SOAP/XML ni de descripcions del servei amb documents WDSL de definició de servei.

Als serveis web SOAP tota la infraestructura es basa en XML i les operacions cal que les defineixi el desenvolupador del servei; són força més complexos, però proporcionen certes capacitats a nivell de seguretat i transaccionalitat que, a vegades, els fan l’única alternativa viable, sobretot en aplicacions empresarials. Tot això fa que REST sigui molt més lleuger i fàcil d’utilitzar que SOAP i, per a determinades arquitectures, sigui una millor opció.

Ens centrarem en la creació i el desplegament de serveis web RESTful amb Java EE 7 i ho farem mitjançant l’API JAX-RS. Noteu que per escriure un servei web RESTful tan sols us caldria un client i un servidor que es puguin comunicar per HTTP, però hauríeu de fer a mà tota la configuració, el parseig de les peticions segons el verb HTTP emprat, el mapatge entre el format de dades de la petició i els objectes Java que representen el domini i enviar les respostes amb el tipus MIME que s’especifiqui a la capçalera de la petició; JAX-RS us estalviarà tota aquesta feina proporcionant-vos un petit conjunt d’anotacions que us permetran desenvolupar còmodament serveis web RESTful.

JAX-RS (de l’anglès Java API for RESTful Web Services) és l’API que inclou l’especificació de Java EE 7 per crear i consumir serveis web basats en REST.

Un servei web RESTful que contesta "Hello World!!!"

Veurem els diferents conceptes bàsics dels serveis web RESTful amb el típic exemple que sempre trobeu als manuals: farem un “Hello World!!!” i el publicarem com a servei web RESTful utilitzant l’API que JAX-RS que proporciona Java EE 7 per fer-ho.

Creació i configuració inicial del projecte

Hem triat per a l’exemple un projecte web amb Maven, però és perfectament vàlid fer-ho amb qualsevol altre tipus de projecte web.

Com que es tracta d’un exemple molt senzill, no ens cal cap projecte de partida; simplement, creeu a NetBeans un nou projecte Maven de tipus Web Application. Per fer-ho, feu File / New Project i us apareixerà l’assistent de creació de projectes. A l’assistent, seleccioneu Maven i Web Application, tal com es veu en la figura.

Figura Creació de projectes a NetBeans

En la següent pantalla (vegeu la figura) triarem el nom del projecte i el paquet per defecte on anirà el codi font. El podeu anomenar “Resthelloioc” i posar el codi font a cat.xtec.ioc.resthelloioc.

Figura Nom del nou projecte

En la següent pantalla (vegeu la figura) de l’assistent deixeu els valors per defecte i polseu Finish.

Figura Configuració del nou projecte

Creació del servei web RESTful

Ja tenim el projecte que ens servirà de base creat. Ara cal que codifiqueu el servei web RESTful que ens ha de tornar la salutació “Hello World!!!”; per fer-ho ens cal decidir primer dues coses: amb quin dels verbs HTTP ha de respondre el servei web i quin URI farem servir per cridar-lo.

Aquest servei web el que ha de fer és obtenir una representació del recurs en format HTML; per tant, haurà de respondre al verb GET.

La decisió sobre quin URI utilitzar és força arbitrària en aquest cas; utilitzarem, per exemple, /hello.

Per tant, a les peticions d’aquest tipus:

GET http://localhost:8080/resthelloioc/hello

Ha de respondre amb:

Hello World!!!

Un cop decidit el funcionament del nostre servei, el següent que us cal fer és codificar una classe Java que implementi la funcionalitat demanada.

Els serveis web RESTful són POJO (de l’anglès Plain Old Java Object) que tenen almenys un mètode anotat amb l’anotació @Path.

Creeu una classe Java que implementarà aquesta funcionalitat, anomeneu-la HelloWorldService i la creeu al paquet cat.xtec.ioc.resthelloioc.service.

Anoteu la classe amb l’anotació @Path(“/hello”) i hi creeu un mètode anomenat, per exemple, sayHello, i l’anoteu amb @GET i @Produces(“text/html”).

  1. package cat.xtec.ioc.resthelloioc.service;
  2.  
  3. import javax.ws.rs.GET;
  4. import javax.ws.rs.Path;
  5. import javax.ws.rs.Produces;
  6.  
  7. @Path("/hello")
  8. public class HelloWorldService {
  9. @GET
  10. @Produces("text/html")
  11. public String sayHello() {
  12. return "Hello World!!!";
  13. }
  14. }

Fixeu-vos que:

  • Hem anotat la classe amb @Path(“/hello”) per indicar que respondrà a les peticions que arribin a l’URL localhost:8080/resthelloworld/hello.
  • Hem anotat el mètode sayHello amb @GET per indicar que respondrà a les peticions HTTP que es facin mitjançant el verb GET.
  • Hem anotat el mètode sayHello amb @Produces(“text/html”) per indicar que respondrà a les peticions HTTP en les quals a la capçalera s’indiqui “text/html” com a tipus MIME, i ho farà produint HTML com a representació del recurs.

I aquesta és tota la feina que ens cal fer per implementar el servei web, JAX-RS farà la resta. Ara tan sols ens manca fer-ne el desplegament al servidor d’aplicacions i provar-lo.

Desplegament del servei web RESTful

Un cop creat el servei web cal que el desplegueu per tal de fer-lo accessible als clients i poder-lo provar.

El procés de desplegament del servei web es fa desplegant l’aplicació Java EE que el conté mitjançant els mecanismes normals de desplegament de qualsevol aplicació Java EE.

El desplegament del servei web com a part de l’aplicació Java EE que el conté és molt senzill: simplement cal que feu Clean and Build i després Run a NetBeans (vegeu la figura) i es farà el desplegament al servidor d’aplicacions que tingueu configurat per al projecte.

Figura ‘Run’ a NetBeans

Si ho feu i el proveu accedint a l’URL que hem configurat: localhost:8080/resthelloioc/hello veureu que el desplegament falla (vegeu la figura).

Figura Error 404 en desplegar

Això és degut al fet que ens cal indicar quines són les classes que ha de tractar com a recursos REST. Això es pot fer de moltes maneres, i una d’elles és crear una classe de configuració anomenada ApplicationConfig al paquet cat.xtec.ioc.resthelloioc.service amb el següent codi:

Si la classe ApplicationConfig no es crea al paquet on hi ha les classes que formen els serveis web ens cladrà afegir cada una de les classes a una col·leccio que té la classe Application de la qual hereta.

  1. package cat.xtec.ioc.resthelloioc.service;
  2.  
  3. import javax.ws.rs.core.Application;
  4.  
  5. @javax.ws.rs.ApplicationPath("rest")
  6. public class ApplicationConfig extends Application {
  7.  
  8. }

On s’indica que cal afegir “/rest” (o el que vulgueu posar) abans del nom del servei web per cridar-lo.

Si proveu ara accedint a l’URL localhost:8080/resthelloioc/rest/hello veureu que el servei web us torna la salutació (vegeu la figura).

Figura Servei web desplegat

Si utilitzeu les eines de debug de Google Chrome, per exemple, podreu veure la petició HTTP feta i la resposta rebuda (vegeu la figura).

Figura Petició i resposta HTTP

El servei web de dades de llibres. Operacions CRUD

CRUD és l’acrònim en anglès per a les operacions de creació (Create), lectura (Read), actualització (Update) i esborrat (Delete).

Veurem els conceptes referents a la creació de serveis web RETSful amb Java EE 7 desenvolupant un servei web RESTful que permeti treballar sobre un catàleg de llibres. Hi farem les operacions típiques CRUD i dues operacions de cerca: la que ens tornarà tots els llibres i una que ens permetrà fer cerques per títol.

Concretament, el servei web que farem tindrà les següents operacions:

  • Consulta d’un llibre mitjançant l’ISBN (operació Read CRUD).
  • Creació d’un llibre al catàleg (operació Create CRUD).
  • Actualització de les dades d’un llibre (operació Update CRUD).
  • Esborrar un llibre del catàleg (operació Delete CRUD).
  • Llistar tots els llibres del catàleg.
  • Cercar llibres per títol.

Per fer-ho farem servir una aplicació web ja desenvolupada que segueixi una arquitectura per capes i hi afegireu una capa de serveis on creareu i publicareu el servei web de gestió del catàleg com a servei web RESTful. La representació que farem servir per als llibres en tot l’exemple serà JSON.

Creació i configuració inicial del projecte

L’aplicació de la qual partirem s’anomena “Restbooksioc” i ens servirà per veure com podem exposar algunes funcionalitats de la capa de serveis d’una aplicació mitjançant serveis web RESTful. Es tracta d’un projecte Spring MVC senzill que segueix una arquitectura típica per capes per tal d’aconseguir una alta reusabilitat, un baix acoblament i una alta cohesió en l’aplicació.

El projecte consta de quatre capes:

  • capa de presentació
  • capa de domini
  • capa de serveis
  • capa de persistència

En l’exemple no farem servir la capa de presentació, ja que l’objectiu no és proporcionar una interfície d’usuari a l’aplicació sinó publicar els mètodes de negoci com a serveis web.

Format JSON

A l’exemple us demanem que treballeu amb una representació JSON. La simplicitat, la lleugeresa i la facilitat de lectura fan ideal aquesta representació per treballar amb aplicacions i dispositius que tenen restriccions pel que fa al volum de dades a intercanviar. Les aplicacions mòbils que consumeixin dades de serveis web RESTful són un molt bon exemple en aquest sentit; la quantitat d’informació que s’intercanviaran client i servidor per fer les operacions és molt menor en una aproximació JSON + RESTful que en una aproximació XML + SOAP.

El model de domini ja el teniu implementat i és molt senzill, només hi ha una entitat Book que representa els llibres del catàleg (vegeu la figura).

Figura Entitat Book

La representació en JSON d’un recurs llibre és la següent:

{	
  "isbn":"9788425343537",
  "author":"Ildefonso Falcones",
  "title":"La catedral del mar"
}

Per fer la transformació entre objectes Java i JSON i a l’inrevés cal que importeu Jersey i Jackson com a artefactes al pom.xml. Aquesta tasca ja l’hem fet per vosaltres a la configuració inicial del projecte; les línies afegides al pom.xml són aquestes:

  1. <dependency>
  2. <groupId>org.glassfish.jersey.core</groupId>
  3. <artifactId>jersey-server</artifactId>
  4. <version>2.22.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.sun.jersey</groupId>
  8. <artifactId>jersey-json</artifactId>
  9. <version>1.19</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.glassfish.jersey.media</groupId>
  13. <artifactId>jersey-media-json-jackson</artifactId>
  14. <version>2.22.1</version>
  15. </dependency>

La capa de serveis serà la que treballarem i haurà de proporcionar un servei web RESTful que permeti als clients fer les següents operacions sobre un catàleg de llibres:

  • Llistar tots els llibres del catàleg.
  • Consulta d’un llibre mitjançant l’ISBN.
  • Creació d’un llibre al catàleg.
  • Actualització de les dades d’un llibre.
  • Esborrar un llibre del catàleg.
  • Cercar llibres per títol.

Repository 'in memory'

Tot i que podríem haver optat per fer l’exemple amb un repositori connectat a una font de dades persistent com una base de dades relacional i utilitzar l’API JPA per definir les entitats del projecte, s’ha considerat que això afegeix “soroll” a l’exemple i us faria portar a terme algunes tasques de configuració que no són pròpies de l’objectiu principal. Per aquest motiu, farem servir un repositori in memory.

La capa de persistència també la teniu implementada i conté l’objecte repositori que permet mapar les dades de la font de dades amb l’objecte de domini. En el nostre cas, per simplicitat, farem servir un repositori in memory que tindrà una llista precarregada amb els llibres del catàleg.

'Bug' a la versió 4.1.1 de Glassfish

Si teniu la versió 4.1.1 de Glassfish sembla que hi ha un error en treballar amb JAX-RS que fa que quan crideu operacions que involucren la transformació entre JSON i les representacions com a objecte Java de les entitats del domini obtingueu la següent excepció:

  1. Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper

Per solucionar-ho cal que descarregueu el fitxer org.eclipse.persistence.moxy.jar que trobareu enllaçat als annexos de la unitat, li tragueu l’extensió .zip, substituïu el que teniu amb el mateix nom al Glassfish, a la carpeta <GLASSFISH_HOME>\glassfish\modules, i reinicieu el servidor.

Creació i prova del servei web RESTful

Descarregueu el codi del projecte “Restbooksioc” de l’enllaç que trobareu als annexos de la unitat, i importeu-lo a NetBeans.

Tot i que també podeu descarregar-vos el projecte en l’estat final des dels annexos, sempre és millor que aneu fent vosaltres tots els passos partint del projecte en l’estat inicial de l’apartat.

Primer ens cal indicar quines són les classes que ha de tractar com a recursos REST. Això es pot fer de moltes maneres, una d’elles és crear una classe de configuració anomenada ApplicationConfig al paquet cat.xtec.ioc.service amb el següent codi:

  1. package cat.xtec.ioc.service;
  2.  
  3. import javax.ws.rs.core.Application;
  4.  
  5. @javax.ws.rs.ApplicationPath("rest")
  6. public class ApplicationConfig extends Application {
  7.  
  8. }

On s’indica que cal afegir “/rest” (o el que vulgueu posar) abans del nom del servei web per cridar-lo.

Un cop fet, crearem una classe que exposarà les operacions que volem; anomenarem la classe BooksRestService, la crearem al paquet cat.xtec.ioc.service i l’anotarem amb @Path(”/books”) i amb @Singleton.

  1. @Path("/books")
  2. @Singleton
  3. public class BooksRestService {
  4.  
  5. }

Quan NetBeans us demani quins imports voleu afegir especifiqueu els del paquet javax.ws.rs.

Fixeu-vos que:

  • L’anotació @Path(”/books”) indica que el recurs estarà accessible a l’URI /books. Accedirem, doncs, als recursos amb l’URL localhost:8080/restbooksioc/rest/books.
  • L’anotació @Singleton ens cal, pel fet que estem utilitzant una repositori in memory i necessitem que el servei web no s’inicialitzi cada vegada que es fa una petició, per tal de no perdre els canvis que anem fent al catàleg de llibres. Si féssiu servir una font de dades persistent no us caldria aquesta anotació, ja que els canvis persistirien a cada petició.

Un cop creada la classe cal que hi afegiu una referència al repositori del catàleg de llibres amb el següent codi:

  1. private BookRepository bookRepository = new InMemoryBookRepository();

I ja podem començar a codificar el primer servei que volem oferir; per exemple, la consulta de tots els llibres del catàleg. Per fer-ho creeu un mètode anomenat getAll amb el següent codi:

  1. @GET
  2. @Produces(MediaType.APPLICATION_JSON)
  3. public List<Book> getAll() {
  4. return this.bookRepository.getAll();
  5. }

Fixeu-vos que:

  • Hem anotat el mètode amb l’anotació @GET per indicar que aquest mètode respondrà a peticions HTTP de tipus GET.
  • Hem anotat el mètode amb @Produces(MediaType.APPLICATION_JSON) per indicar que el resultat del mètode serà del tipus MIME “application/json”, ja que tornarem la llista de llibres en format JSON.

Per provar si funciona, desplegueu el projecte fent Run a NetBeans i accediu amb un navegador a l’URL localhost:8080/restbooksioc/rest/books; si tot ha anat bé veureu la representació JSON del catàleg de llibres al navegador:

[{"isbn":"9788425343537","author":"Ildefonso Falcones","title":"La catedral del mar"},
{"isbn":"9788467009477","author":"Jose Maria Peridis Perez","title":"La luz y el misterio de las catedrales"}]

Passem a crear ara el servei de consulta de llibres per ISBN (l’operació Read de CRUD); per fer-ho, creeu un mètode anomenat find amb el següent codi:

  1. @GET
  2. @Path("{isbn}")
  3. @Produces(MediaType.APPLICATION_JSON)
  4. public Book find(@PathParam("isbn") String isbn) {
  5. return this.bookRepository.get(isbn);
  6. }

Hem anotat el mètode amb l’anotació @GET per indicar que aquest mètode respondrà a peticions HTTP de tipus GET.

Hem anotat el mètode amb @Produces(MediaType.APPLICATION_JSON) per indicar que el resultat del mètode serà del tipus MIME “application/json”, ja que tornarem la informació del llibre en format JSON.

Hem anotat el mètode amb l’anotació @Path(“{isbn}”) per indicar que la informació del llibre la tornarem quan ens arribin peticions GET a l’URI /books/{isbn}; és a dir, el que posem darrere de /books serà l’ISBN del llibre que volem consultar. Les anotacions @Path dels mètodes sempre s’afegeixen a l’anotació de l’arrel del recurs que heu definit a la classe.

El paràmetre que rep el mètode s’ha anotat amb l’anotació @PathParam(“isbn”). Aquesta és la forma que proporciona JAX-RS per extreure els paràmetres d’una petició. En aquest cas estem extraient un paràmetre del path, de l’URI, i el passem com a String al mètode find.

JAX-RS proporciona un ampli conjunt d’anotacions per fer aquesta tasca fàcil, entre elles destaquem @PathParam, @QueryParam, @MatrixParam, @CookieParam, @HeaderParam i @FormParam.

Per exemple, podríem utilitzar @QueryParam(“year”) per extreure un paràmetre que vingués en una petició d’aquesta forma: localhost:8080/restbooksioc/rest/books?year=2016.

Per provar si funciona, desplegueu el projecte fent Run a NetBeans i accediu amb un navegador a l’URL localhost:8080/restbooksioc/rest/books/9788425343537; si tot ha anat bé, veureu la representació JSON del llibre consultat al navegador:

[{"isbn":"9788425343537","author":"Ildefonso Falcones","title":"La catedral del mar”}]

Creem ara el servei que permeti donar d’alta un llibre al catàleg (l’operació Create de CRUD); per fer-ho, creeu un mètode anomenat create amb el següent codi:

  1. @POST
  2. @Consumes(MediaType.APPLICATION_JSON)
  3. public void create(Book book) {
  4. this.bookRepository.add(book);
  5. }

Hem anotat el mètode amb l’anotació @POST per indicar que aquest mètode respondrà a peticions HTTP de tipus POST.

Hem anotat el mètode amb @Consumes(MediaType.APPLICATION_JSON) per indicar que la informació del llibre que es vol donar d’alta vindrà en format JSON.

Fixeu-vos que tan sols amb aquesta informació JAX-RS és capaç, quan rep una petició POST a l’ URI /books amb una representació JSON d’un llibre, de crear un objecte de tipus Book i passar-lo al mètode create. No és fantàstic?

Swagger i Postman

Per documentar i provar API RESTful teniu moltes alternatives, entre elles destaquem Swagger swagger.io i Postman www.getpostman.com, que és una extensió per al navegador Google Chrome. </note>

Ara tocaria provar aquesta funcionalitat, però tenim un problema: com podem enviar peticions POST sense fer una aplicació web amb un formulari? Per fer una petició GET tan sols hem de posar l’URL al navegador i ja ho tenim, però per fer peticions POST ens caldrà alguna utilitat extra. La nostra proposta és que feu servir cURL, que és una eina molt útil per fer peticions HTTP de diferents tipus i és multiplataforma. Si feu servir Linux possiblement ja la tingueu instal·lada al sistema; en cas que utilitzeu, Windows la podeu descarregar en el següent enllaç: curl.haxx.se/download.html, o bé aconseguir un .msi que us faciliti la instal·lació.

Afegiu el paràmete -v (verbose) a les crides a cURL si voleu veure més informació sobre les peticions i respostes que feu.

La sintaxi de cURL per fer peticions és molt senzilla; per exemple, per consultar tots els llibres del catàleg feu un command prompt:

curl localhost:8080/restbooksioc/rest/books

Per provar la funcionalitat que permet afegir un llibre al catàleg desplegueu el projecte fent Run a NetBeans i feu una petició POST a l’URL localhost:8080/restbooksioc/rest/books especificant la informació del llibre amb JSON; això ho podeu fer amb cURL i la següent comanda:

curl -H "Content-Type: application/json" -X POST -d "{\"isbn\":\"9788499301518\",\"author\":\"J.K. Rowling\",\"title\":\"Harry Potter y la piedra filosofal\"}" http://localhost:8080/restbooksioc/rest/books

Fixeu-vos-hi: li diem que farem una petició POST amb el paràmetre -X, li especifiquem el format JSON del llibre amb el paràmetre -d i indiquem que el format és JSON especificant-ho a la capçalera amb el paràmetre -H.

Executeu la comanda anterior i després consulteu el llistat de llibres amb:

curl localhost:8080/restbooksioc/rest/books

Si tot ha anat bé, veureu que el nou llibre s’ha afegit al catàleg de llibres:

[{"isbn":"9788499301518","author":"J.K. Rowling","title":"Harry Potter y la piedra filosofal"},
{"isbn":"9788425343537","author":"Ildefonso Falcones","title":"La catedral del mar"},
{"isbn":"9788467009477","author":"Jose Maria Peridis Perez","title":"La luz y el misterio de las catedrales"}]

Creem ara el servei que permeti modificar la informació d’un llibre del catàleg (l’operació Update de CRUD); per fer-ho, creeu un mètode anomenat update amb el següent codi:

  1. @PUT
  2. @Consumes(MediaType.APPLICATION_JSON)
  3. public void edit(Book book) {
  4. this.bookRepository.update(book);
  5. }

Les consideracions en aquest cas són les mateixes que hem vist per al cas de la creació de llibres, l’únic que canvia és que farem servir el verb PUT en lloc del verb POST.

Per provar la funcionalitat que permet modificar la informació d’un llibre del catàleg desplegueu el projecte fent Run a NetBeans i feu una petició PUT a l’URL localhost:8080/restbooksioc/rest/books especificant la nova informació del llibre amb JSON; això ho podeu fer amb cURL i la següent comanda:

curl -H "Content-Type: application/json" -X PUT -d "{\"isbn\":\"9788425343537\",\"author\":\" Ildefonso Falcones\",\"title\":\" LA CATEDRAL DEL MAR \"}" http://localhost:8080/restbooksioc/rest/books

Executeu la comanda anterior i després consulteu la informació del llibre que heu modificat amb:

curl localhost:8080/restbooksioc/rest/books/9788425343537

Si tot ha anat bé, veureu que el títol del llibre ha canviat a majúscules:

{"isbn":"9788425343537","author":" Ildefonso Falcones","title":" LA CATEDRAL DEL MAR "}

Creem ara el servei que permeti esborrar un llibre del catàleg (l’operació Delete de CRUD); per fer-ho, creeu un mètode anomenat remove amb el següent codi:

  1. @DELETE
  2. @Path("{isbn}")
  3. public void remove(@PathParam("isbn") String isbn) {
  4. this.bookRepository.delete(isbn);
  5. }

Les consideracions en aquest cas són les mateixes que hem vist per al cas de la consulta de llibres per ISBN, l’únic que canvia és que farem servir el verb DELETE en lloc del verb GET.

Per provar la funcionalitat que permet esborrar un llibre del catàleg desplegueu el projecte fent Run a NetBeans i feu una petició DELETE a l’URL localhost:8080/restbooksioc/rest/books especificant l’ISBN del llibre que volem esborrar; això ho podeu fer amb cURL i la següent comanda:

curl -X DELETE http://localhost:8080/restbooksioc/rest/books/9788425343537

Executeu la comanda anterior i després consulteu el llistat de llibres amb:

curl localhost:8080/restbooksioc/rest/books

Si tot ha anat bé, veureu que el llibre ja no el teniu al catàleg de llibres:

[{"isbn":"9788467009477","author":"Jose Maria Peridis Perez","title":"La luz y el misterio de las catedrales"}]

Finalment, codificarem una operació que ens permeti cercat llibres per títol; per fer-ho, creeu un mètode anomenat findByTitle amb el següent codi:

  1. @GET
  2. @Path("findByTitle/{title}")
  3. @Produces(MediaType.APPLICATION_JSON)
  4. public List<Book> findByTitle(@PathParam("title") String title) {
  5. return this.bookRepository.findByTitle(title);
  6. }

Si voleu cercar títols de llibre que continguin espais en blanc amb cURL ho haureu de fer posant %20 enlloc de l’espai en blanc.

Les consideracions en aquest cas són les mateixes que hem vist per al cas d’un llibre per ISBN, l’únic que canvia és que l’anotació @Path ara comença amb findByTitle i després té el paràmetre {title} per indicar que la consulta de llibres per títol la tornarem quan ens arribin peticions GET a l’URI /books/findByTitle/{title}, és a dir, el que posarem darrere del /books/findByTitle/ serà el títol que volem cercar.

Per provar la funcionalitat que permet cercar un llibre del catàleg per títol desplegueu el projecte fent Run a NetBeans i feu una petició GET a l’URL localhost:8080/restbooksioc/rest/books/findByTitle especificant el títol que volem cercar; això ho podeu fer amb cURL i la següent comanda (cercarem tots els llibres que tenen la paraula “catedral” al títol):

curl http://localhost:8080/restbooksioc/rest/books/findByTitle/catedral

Executeu la comanda anterior i, si tot ha anat bé, veureu que us torna els dos llibres del catàleg que tenen la paraula “catedral” al títol:

[{"isbn":"9788467009477","author":"Jose Maria Peridis Perez","title":"La luz y el misterio de las catedrales"},
{"isbn":"9788425343537","author":"Ildefonso Falcones","title":"La catedral del mar"}] 

I amb això ja heu codificat i provat el servei web RESTful que us permet treballar amb el catàleg de llibres.

El codi final de la classe BooksRestService és el següent:

  1. @Path("/books")
  2. @Singleton
  3. public class BooksRestService {
  4.  
  5. private BookRepository bookRepository = new InMemoryBookRepository();
  6.  
  7. @GET
  8. @Produces(MediaType.APPLICATION_JSON)
  9. public List<Book> getAll() {
  10. return this.bookRepository.getAll();
  11. }
  12.  
  13. @GET
  14. @Path("{isbn}")
  15. @Produces(MediaType.APPLICATION_JSON)
  16. public Book find(@PathParam("isbn") String isbn) {
  17. return this.bookRepository.get(isbn);
  18. }
  19.  
  20. @GET
  21. @Path("findByTitle/{title}")
  22. @Produces(MediaType.APPLICATION_JSON)
  23. public List<Book> findByTitle(@PathParam("title") String title) {
  24. return this.bookRepository.findByTitle(title);
  25. }
  26.  
  27. @POST
  28. @Consumes(MediaType.APPLICATION_JSON)
  29. public void create(Book book) {
  30. this.bookRepository.add(book);
  31. }
  32.  
  33. @PUT
  34. @Consumes(MediaType.APPLICATION_JSON)
  35. public void edit(Book book) {
  36. this.bookRepository.update(book);
  37. }
  38.  
  39. @DELETE
  40. @Path("{isbn}")
  41. public void remove(@PathParam("isbn") String isbn) {
  42. this.bookRepository.delete(isbn);
  43. }
  44. }

Què s'ha après?

En aquest apartat heu vist les bases pel desenvolupament dels serveis web RESTful amb Java EE 7 i les heu treballat de forma pràctica mitjançant exemples.

Concretament, heu après:

  • Les nocions bàsiques dels serveis web RESTful amb Java EE.
  • A desenvolupar, desplegar i provar un servei web RESTful senzill amb Java EE.
  • A desenvolupar, desplegar i provar un servei web RESTful complex amb Java EE que inclou operacions CRUD sobre un recurs.

Per aprofundir en aquests conceptes i veure com us pot ajudar NetBeans en la creació i el consum de serveis web RESTful us recomanem la realització de les activitats associades a aquest apartat.

Anar a la pàgina anterior:
Annexos
Anar a la pàgina següent:
Activitats