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
.