La solució de l’exercici s’ha provat amb la versió 4.1.1 de GlassFish.
En aquesta activitat fareu “enginyeria inversa”: primer creareu la taula a la base de dades que contindrà el catàleg de llibres, després creareu una entitat JPA que representarà el model del domini i, a partir d’aquesta entitat, creareu el servei web RESTful, que implementarà les operacions CRUD per a l’entitat.
Començareu l’activitat creant la taula a la base de dades que contindrà el catàleg de llibres. Per fer-ho, aneu a la pestanya Services de NetBeans i a Databases / jdbc:derby:localhost:1527/sample [app on APP], feu clic amb el botó dret i Connect. Un cop connectada la base de dades aneu a APP / Tables, feu clic amb el botó dret i creeu una nova taula anomenada “BOOK” (vegeu la figura).
Creeu tres columnes a la taula i anomeneu-les “ISBN” (que serà la clau primària), “AUTHOR” i “TITLE”(vegeu la figura).
Afegiu alguns llibres a la taula, tal com es pot veure en la figura.
Creeu el projecte “nb-restbooksioc” a NetBeans. Per fer-ho, feu New Project… / Maven / Web Application (vegeu la figura).
Polseu Next i ompliu el formulari especificant el nom del projecte (vegeu la figura).
En la següent pantalla (vegeu la figura) de l’assistent, deixeu els valors per defecte i polseu Finish.
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. Afegiu aquestes línies al pom.xml:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.1</version>
</dependency>
Ja teniu la taula que guardarà els llibres a la base de dades creada i el projecte que us servirà de base també creat i configurat. Ara generareu una entitat JPA que faci el mapatge de les dades de la taula de llibres en un objecte Java que anomenareu Book. Per fer-ho, feu clic amb el botó dret al projecte “nb-restbooksioc” i seleccioneu New / Entity Classes from Database (vegeu la figura).
Trieu el datasource jdbc/sample i la taula “BOOK” i polseu Next (vegeu la figura).
A la següent pantalla de l’assistent deixareu els valors per defecte i polsareu Next (vegeu la figura).
Per a les opcions de mapatge també deixareu els valors per defecte i polsareu Finish (vegeu la figura).
NetBeans ens ha generat una entitat JPA anomenada Book al paquet cat.xtec.ioc.nb.restbooksioc amb tot el codi necessari per fer-la persistent a la taula “BOOK”. No entrarem en detall en aquest codi, ja que no és l’objectiu de l’activitat.
@Table(name = "BOOK")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Book.findAll", query = "SELECT b FROM Book b"),
@NamedQuery(name = "Book.findByIsbn", query = "SELECT b FROM Book b WHERE b.isbn = :isbn"),
@NamedQuery(name = "Book.findByAuthor", query = "SELECT b FROM Book b WHERE b.author = :author"),
@NamedQuery(name = "Book.findByTitle", query = "SELECT b FROM Book b WHERE b.title = :title")})
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 30)
@Column(name = "ISBN")
@Size(max = 255)
@Column(name = "AUTHOR")
@Size(max = 255)
@Column(name = "TITLE")
}
this.isbn = isbn;
}
return isbn;
}
public void setIsbn
(String isbn
) { this.isbn = isbn;
}
return author;
}
public void setAuthor
(String author
) { this.author = author;
}
return title;
}
public void setTitle
(String title
) { this.title = title;
}
@Override
public int hashCode() {
int hash = 0;
hash += (isbn != null ? isbn.hashCode() : 0);
return hash;
}
@Override
public boolean equals
(Object object
) { // TODO: Warning - this method won't work in the case the id fields are not set
if (!(object
instanceof Book)) { return false;
}
if ((this.isbn == null && other.isbn != null) || (this.isbn != null && !this.isbn.equals(other.isbn))) {
return false;
}
return true;
}
@Override
return "cat.xtec.ioc.nb.restbooksioc.Book[ isbn=" + isbn + " ]";
}
}
Un cop teniu ja creada l’entitat JPA Book ja podeu generar el servei web RESTful, que us permetrà fer les operacions CRUD al catàleg de llibres.
Per fer-ho, feu clic amb el botó dret al projecte “nb-restbooksioc” i seleccioneu New / RESTful Web Services from Entity Classes… (vegeu la figura).
Seleccioneu l’entitat JPA que acabeu de crear i polseu Next (vegeu la figura).
Trieu el paquet on voleu que us generi el codi del servei web, per exemple a cat.xtec.ioc.nb.restbooksioc.service (vegeu la figura).
Feu clic a Finish i veureu que s’han generat tres classes al paquet cat.xtec.ioc.nb.restbooksioc.service:
La classe AbstractFacade, que conté la implementació dels mètodes JPA per fer persistent l’entitat Book.
La classe
ApplicationConfig, on, per defecte, us ha posat que els recursos RESTful seran accessibles al
PATH webresources. Això implica que els recursos seran accessibles a l’
URL localhost:8080/nb-restbooksioc/webresources.
La classe BookFacadeREST, que és la implementació del servei web RESTful amb les operacions CRUD sobre el catàleg de llibres.
El codi generat a la classe BookFacadeREST és el següent:
@Stateless
@Path("books")
public class BookFacadeREST extends AbstractFacade<Book> {
@PersistenceContext(unitName = "cat.xtec.ioc_nb-restbooksioc_war_1.0-SNAPSHOTPU")
private EntityManager em;
public BookFacadeREST() {
}
@POST
@Override
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void create
(Book entity
) { super.create(entity);
}
@PUT
@Path("{id}")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void edit
(@PathParam
("id") String id,
Book entity
) { super.edit(entity);
}
@DELETE
@Path("{id}")
public void remove
(@PathParam
("id") String id
) { super.remove(super.find(id));
}
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
return super.find(id);
}
@GET
@Override
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public List<Book> findAll() {
return super.findAll();
}
@GET
@Path("{from}/{to}")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public List
<Book
> findRange
(@PathParam
("from") Integer from, @PathParam
("to") Integer to
) { return super.findRange(new int[]{from, to});
}
@GET
@Path("count")
@Produces(MediaType.TEXT_PLAIN)
return String.
valueOf(super.
count()); }
@Override
protected EntityManager getEntityManager() {
return em;
}
}
Podeu veure que s’han generat les següents operacions amb les corresponents anotacions JAX-RS:
Operació find: consulta d’un llibre mitjançant l’identificador (operació Read CRUD).
Operació create: creació d’un llibre al catàleg (operació Create CRUD).
Operació update: actualització de les dades d’un llibre (operació Update CRUD).
Operació remove: esborrar un llibre del catàleg (operació Delete CRUD).
Operació findAll: llistar tots els llibres del catàleg.
Per fer més entenedores les URI amb les quals provarem el servei web, canvieu @Path(“cat.xtec.ioc.nb.restbooksioc.book”) per @Path(“books”).
Ara sols cal que feu Clean and Build i després Run a NetBeans i es farà el desplegament al servidor d’aplicacions que tingueu configurat per al projecte (vegeu la figura).
I utilitzeu cURL per fer provar les diferents operacions implementades; us en posem un parell com a exemple, la resta les podeu provar vosaltres mateixos.
Consulta de tots els llibres del catàleg:
curl localhost:8080/nb-restbooksioc/webresources/books
la sortida seria aquesta:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books>
<book>
<author>Ildefonso Falcones</author>
<isbn>9788425343537</isbn>
<title>La catedral del mar</title>
</book>
<book>
<author>Jose Maria Peridis Perez</author>
<isbn>9788467009477</isbn>
<title>La luz y el misterio de las catedrales</title>
</book>
</books>
Alta d’un llibre al catàleg:
curl -H "Content-Type: application/xml" -X POST -d "<book><author>J.K. Rowling</author><isbn>9788499301518</isbn><title>Harry Potter y la piedra filosofal</title></book>" localhost:8080/nb-restbooksioc/webresources/books
Executeu la comanda anterior i després consulteu el llistat de llibres amb:
curl localhost:8080/nb-restbooksioc/webresources/books
Si tot ha anat bé veureu que el nou llibre s’ha afegit al catàleg de llibres:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books>
<book>
<author>Ildefonso Falcones</author>
<isbn>9788425343537</isbn>
<title>La catedral del mar</title>
</book>
<book>
<author>Jose Maria Peridis Perez</author>
<isbn>9788467009477</isbn>
<title>La luz y el misterio de las catedrales</title>
</book>
<book>
<author>J.K. Rowling</author>
<isbn>9788499301518</isbn>
<title>Harry Potter y la piedra filosofal</title>
</book>
</books>
El codi de la solució d’aquesta activitat el podeu descarregar del següent
.