Escolar Documentos
Profissional Documentos
Cultura Documentos
Licence
Creative Commons
Contrat Paternit
Partage des Conditions Initiales l'Identique
keulkeul.blogspot.com
2.0 France
http://creativecommons.org/licenses/by-sa/2.0/fr
JAX-RS - M. Baron - Page 2
Plan du cours
Gnralits JAX-RS
Premier service Web JAX-RS
Rappels HTTP (Requte et Rponse)
Dveloppement Serveur
Chemin de ressource @Path
Paramtres des requtes
keulkeul.blogspot.com
Dveloppement Client
Outils
Droulement du cours
Pdagogie du cours
Illustration avec de nombreux exemples qui sont disponibles
ladresse http://mbaron.developpez.com/soa/jaxrs
Des bulles daide tout au long du cours
Survol des principaux concepts en vitant une prsentation exhaustive
Logiciels utiliss
Navigateur Web, Eclipse 3.6, Tomcat 6, Maven 3
keulkeul.blogspot.com
Pr-requis
Remerciements
Djug
Ressources
Billets issus de Blog
zenoconsulting.wikidot.com/blog:1
blog.smile.fr/JAX-RS-le-specification-Java-pour-implementer-les-services-REST
blogs.sun.com/enterprisetechtips/entry/consuming_restful_web_services_with
www.touilleur-express.fr/2008/04/25/jsr-311-jax-rs-rest-une-histoire-de-restaurant/
eclipsedriven.blogspot.com/2010/12/writing-jax-rs-rest-api-server-with.html
blogs.sun.com/sandoz
Articles
www.oracle.com/technetwork/articles/javase/index-137171.html
wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features
jsr311.java.net/nonav/releases/1.1/index.html
keulkeul.blogspot.com
en.wikipedia.org/wiki/JAX-RS
www.devx.com/Java/Article/42873
jcp.org/en/jsr/summary?id=311
www.vogella.de/articles/REST/article.html
www.infoq.com/articles/rest-introduction
download.oracle.com/javaee/6/tutorial/doc/giepu.html
docs.sun.com/app/docs/doc/820-4867/820-4867
Ressources (suite)
Articles (suite)
jersey.java.net/nonav/documentation/latest/user-guide.html
java.sun.com/developer/technicalArticles/WebServices/jax-rs/index.html
www.dotmyself.net/documentation/7.html
www.dotmyself.net/documentation/6.html
www.dotmyself.net/documentation/13.html
Prsentations
www.slideshare.net/caroljmcdonald/td09restcarol
www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-environment
www.slideshare.net/jugtoulouse/rest-nicolas-zozol-jug-toulouse-20100615
keulkeul.blogspot.com
developers.sun.com/learning/javaoneonline/2008/pdf/TS-5425.pdf
Cours
jersey.java.net/nonav/documentation/latest/user-guide.html
Ressources : Bibliothque
RESTful Java
Auteur : Bill Burke
diteur : Oreilly
Edition : Nov. 2009 - 320 pages - ISBN : 0596158041
keulkeul.blogspot.com
keulkeul.blogspot.com
keulkeul.blogspot.com
keulkeul.blogspot.com
groupId : com.sun.jersey
artifactId : jersey-server
version : 1.4
WADL
Servlet
PHP
keulkeul.blogspot.com
JAVA
HTTP
Serveur
Web
Conteneur Java
Classes JAVA annotes
implmentant le
service web
Diffrentes APIs
possibles pour la gestion
du client en Java
Couche Cliente
JAX-RS
Utilisation du Service
Web par envoie /
rception de contenu
HTTP
Approche Bottom / Up
.NET
Couche Serveur
keulkeul.blogspot.com
@Path("/hello")
public class HelloWorldResource {
Lecture de la ressource
HelloWorld via une requte HTTP
de type GET
@GET
@Produces("text/plain")
public String getHelloWorld() {
return "Hello World from text/plain";
}
keulkeul.blogspot.com
HelloWorldResource.java du projet
HelloWorldRestWebService
keulkeul.blogspot.com
index.html
web.xml
WEB-INF
HelloWorldRestWebService.war
classes
keulkeul.blogspot.com
lib
HelloWorldResource.class
jersey-core-1.x.jar
jersey-server-1.x.jar
jsr311-api-1.0.jar
keulkeul.blogspot.com
web.xml du projet
HelloWorldRestWebService
keulkeul.blogspot.com
keulkeul.blogspot.com
Le type de mthode
de la requte GET,
POST, ...
Protocole HTTP
avec la version :
1.0 ou 1.1
keulkeul.blogspot.com
Diffrentes informations
concernant le navigateur,
lutilisateur, ...
La ligne blanche
est obligatoire
www.exemple.com/hello?key1=titi&key2=raoul&
keulkeul.blogspot.com
Donne des
informations sur
le statut : OK
keulkeul.blogspot.com
HTTP/<Version><Status><Commentaire Status>
Content-Type:<Type MIME du contenu>
[<Champ den-tte>:<Valeur>]
...
Ligne blanche
Document
Diffrentes informations
concernant le serveur, ...
La ligne blanche
est obligatoire
Le document peut
contenir du texte non
format, du code HTML,
...
JAX-RS - M. Baron - Page 24
keulkeul.blogspot.com
ETag =
Location =
@Path
Une classe Java doit tre annote par @path pour quelle
puisse tre traite par des requtes HTTP
Lannotation @path sur une classe dfinit des ressources
appeles racines (Root Resource Class)
La valeur donne @path correspond une expression URI
relative au contexte de lapplication Web
keulkeul.blogspot.com
http://localhost:8088/libraryrestwebservice/books
Adresse du
Serveur
Port
Contexte de
l'application WEB
URI de la
ressource
@Path
Lannotation @path peut galement annoter des mthodes
de la classe (facultatif)
LURI rsultante est la concatnation de lexpression du
@path de la classe avec lexpression du @path de la mthode
Exemple
keulkeul.blogspot.com
Requtes HTTP
de types GET
/books
@Path("/books")
public class BookResource {
@GET
public String getBooks() {
...
}
/books/borrowed
Serveur Web
BookResource.java du projet
LibraryRestWebService
@GET
@Path("/borrowed")
public String getBorrowedBooks() {
...
}
}
Conteneur de Servlets
keulkeul.blogspot.com
keulkeul.blogspot.com
@GET
@Path("{id}")
public String getBookById(@PathParam("id") int id) {
return "Java For Life " + id;
}
@GET
@Path("name-{name}-editor-{editor}")
public String getBookByNameAndEditor(@PathParam("name") String name,
@PathParam("editor") String editor)
return "Starcraft 2 for Dummies (Name:" + name + " - Editor:" + editor + ")";
}
}
/books/name-sc2-editor-oreilly
BookResource.java du projet
LibraryRestWebService
keulkeul.blogspot.com
@GET
@Path("{id : .+}/editor")
public String getBookEditorById(@PathParam("id") String id) {
return "OReilly";
}
@GET
@Path("original/{id : .+}")
public String getOriginalBookById(@PathParam("id") String id) {
return "Java For Life 2";
}
}
BookResource.java du projet
LibraryRestWebService
/books/original/123/path1/path2
JAX-RS - M. Baron - Page 31
keulkeul.blogspot.com
keulkeul.blogspot.com
SpecificBookResource.java du projet
LibraryRestWebService
/books/specific/123
JAX-RS - M. Baron - Page 33
keulkeul.blogspot.com
keulkeul.blogspot.com
Requtes HTTP
GET,
POST,
PUT et
DELETE
/books/{id}
GET : rcupre un livre
PUT : mise jour dun livre
DELETE : effacer un livre
Serveur Web
Conteneur de Servlets
keulkeul.blogspot.com
Rcupre un livre
Effacer un livre
BookResource.java du projet
LibraryRestWebService
Paramtres de requtes
JAX-RS fournit des annotations pour extraire des paramtres
dune requte
Elles sont utilises sur les paramtres des mthodes des
ressources pour raliser linjection du contenu
Liste des diffrentes annotations disponibles
@PathParam : extraire les valeurs des Template Parameters
@QueryParam : extraire les valeurs des paramtres de requte
keulkeul.blogspot.com
keulkeul.blogspot.com
suivants
Les types primitifs sauf char et les classes qui les encapsulent
Toutes classes ayant un constructeur avec paramtre de type String
Toutes classes ayant la mthode statique valueOf(String)
/books/123/path1/path2/editor
@GET
@Path("{id}")
public String getBookById(@PathParam("id") int id) {
return "Java For Life " + id;
}
keulkeul.blogspot.com
/books/name-sc2-editor-oreilly
@GET
@Path("name-{name}-editor-{editor}")
public String getBookByNameAndEditor(@PathParam("name") String name,
@PathParam("editor") String editor)
return "Starcraft 2 for Dummies (Name:" + name + " - Editor:" + editor + ")";
}
}
BookResource.java du projet
LibraryRestWebService
keulkeul.blogspot.com
/books/queryparameters?name=harry&isbn=1-111111-11&isExtended=true
@Path("/books")
Injection de valeurs par dfaut
public class BookResource {
...
si les valeurs des paramtres
@GET
ne sont pas fournies
@Path("queryparameters")
public String getQueryParameterBook(
@DefaultValue("all") @QueryParam("name") String name,
@DefaultValue("?-???????-?") @QueryParam("isbn") String isbn,
@DefaultValue("false") @QueryParam("isExtended") boolean isExtented) {
return name + " " + isbn + " " + isExtented;
}
}
BookResource.java du projet
LibraryRestWebService
keulkeul.blogspot.com
Exemple
@Path("/books")
public class BookResource {
...
@POST
@Path("createfromform")
@Consumes("application/x-www-form-urlencoded")
public String createBookFromForm(@FormParam("name") String name) {
System.out.println("BookResource.createBookFromForm()");
return name;
}
}
BookResource.java du projet
LibraryRestWebService
keulkeul.blogspot.com
Exemple
@Path("/books")
public class BookResource {
...
@GET
@Path("headerparameters")
public String getHeaderParameterBook(
@DefaultValue("all") @HeaderParam("name") String name,
@DefaultValue("?-???????-?") @HeaderParam("isbn") String isbn,
@DefaultValue("false") @HeaderParam("isExtended") boolean isExtented) {
return name + " " + isbn + " " + isExtented;
}
}
BookResource.java du projet
LibraryRestWebService
keulkeul.blogspot.com
Certains de ces objets permettent dobtenir les mmes informations que les prcdentes annotations lies aux paramtres
JAX-RS - M. Baron - Page 43
keulkeul.blogspot.com
http://localhost:8088/libraryrestwebservice/books/informationfromuriinfo/test?toto=ddd
@Path("/books")
public class BookResource {
BookResource.java du projet
...
LibraryRestWebService
@GET
@Path("informationfromuriinfo/{name}")
public String getInformationFromUriInfo(@Context UriInfo uriInfo,
@PathParam("name") String name) {
System.out.println("getPath(): " + uriInfo.getPath());
List<PathSegment> pathSegments = uriInfo.getPathSegments();
...
MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters();
...
MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
...
System.out.println("getAbsolutePath(): " + uriInfo.getAbsolutePath());
System.out.println("getBaseUri(): " + uriInfo.getBaseUri());
System.out.println("getRequestUri(): " + uriInfo.getRequestUri());
return ...;
}
}
keulkeul.blogspot.com
keulkeul.blogspot.com
@Path("/books")
public class BookResource {
...
@GET
@Path("informationfromhttpheaders/{name}")
public String getInformationFromHttpHeaders(@Context HttpHeaders httpheaders) {
Map<String, Cookie> cookies = httpheaders.getCookies();
Set<String> currentKeySet = cookies.keySet();
for (String currentCookie : currentKeySet) {
System.out.println(currentCookie);
}
MultivaluedMap<String, String> requestHeaders = httpheaders.getRequestHeaders();
Set<String> requestHeadersSet = requestHeaders.keySet();
for (String currentHeader : requestHeadersSet) {
System.out.println(currentHeader);
}
return "";
}
}
BookResource.java du projet
LibraryRestWebService
48
Type MIME
accept par le
client
keulkeul.blogspot.com
HTTP/1.1 200 OK
Date: Wed, 05 January 2010 14:44:55 GMT
Server: Jetty(6.1.14)
Content-Type: text/html
Type MIME de la
rponse
<html>
<title>Details</title>
<body>
<h1>Ce livre est une introduction sur la vie</h1>
</body>
</html>
keulkeul.blogspot.com
Gestion du contenu
Prcdemment nous sommes focaliss sur les informations
contenues dans len-tte dune requte
JAX-RS permet galement de manipuler le contenu du corps
dune requte et dune rponse
JAX-RS peut automatiquement effectuer des oprations de
srialisation et d-srialisation vers un type Java spcifique
*/* : byte[]
text/* : String
keulkeul.blogspot.com
keulkeul.blogspot.com
@Path("/contentbooks")
public class BookResource {
@PUT
@Path("inputstream")
public void updateContentBooksWithInputStream(InputStream is) throws IOException {
byte[] bytes = readFromStream(is);
String input = new String(bytes);
System.out.println(input);
}
private byte[] readFromStream(InputStream stream) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1000]; int wasRead = 0;
do {
wasRead = stream.read(buffer);
if (wasRead > 0) { baos.write(buffer, 0, wasRead); }
} while (wasRead > -1);
return baos.toByteArray();
}
@Path("inputstream")
@GET
@Produces(MediaType.TEXT_XML)
public InputStream getContentBooksWithInputStream() throws FileNotFoundException {
return new FileInputStream("c:\\example.xml");
}
}
BookResource.java du projet
LibraryContentRestWebService
keulkeul.blogspot.com
@Path("/contentbooks")
public class BookResource {
@Path("file")
@PUT
public void updateContentBooksWithFile(File file) throws IOException {
byte[] bytes = readFromStream(new FileInputStream(file));
String input = new String(bytes);
System.out.println(input);
}
JAX-RS cre un fichier
@Path("file")
@GET
@Produces(MediaType.TEXT_XML)
public File getContentBooksWithFile() {
File file = new File("c:\\example.xml");
return file;
}
temporaire
partir du fichier donn
...
}
BookResource.java du projet
LibraryContentRestWebService
keulkeul.blogspot.com
@Path("string")
@GET
@Produces(MediaType.TEXT_XML)
public String getContentBooksWithString() {
return "<?xml version=\"1.0\"?>" + "<details>Ce livre est une introduction sur la vie" +
"</details>";
}
...
}
BookResource.java du projet
LibraryContentRestWebService
keulkeul.blogspot.com
keulkeul.blogspot.com
keulkeul.blogspot.com
Book.java du projet
LibraryContentRestWebService
JAX-RS - M. Baron - Page 57
keulkeul.blogspot.com
@Path("jaxbxml")
@GET
@Produces("application/xml")
public Book getContentBooksWithJAXBXML() {
Book current = new Book();
current.setIsbn("123-456-789");
current.setName("Harry Toper");
return current;
}
...
}
BookResource.java du projet
LibraryContentRestWebService
@Path("/contentbooks")
public class BookResource {
...
@Path("jaxbxml")
@Consumes("application/xml")
@POST
public void updateContentBooksWithJAXBElementXML(JAXBElement<Book> currentJAXBElemnt) {
Book current = currentJAXBElemnt.getValue();
keulkeul.blogspot.com
keulkeul.blogspot.com
Response
Actuellement, tous les services dvelopps retournaient soit
un type Void soit un type Java dfini par le dveloppeur
JAX-RS facilite la construction de rponses en permettant de
de choisir un code de retour
de fournir des paramtres dans len-tte
de retourner une URI,
keulkeul.blogspot.com
- M. Baron - Page 61
Response
Principales mthodes de la classe Response
ResponseBuilder created(URI location) : Modifie la valeur de Location
dans len-tte, utiliser pour une nouvelle ressource cre
keulkeul.blogspot.com
Response
Exemple : Prciser code retour et ajouter informations dans
len-tte de la rponse
BookResource.java du projet
keulkeul.blogspot.com
LibraryContentRestWebService
@Path("/contentbooks")
public class BookResource {
Statut OK
...
@Path("response")
@GET
public Response getBooks() {
return Response
Trois paramtres
.status(Response.Status.OK)
.header("param1", "Bonjour")
.header("param2", "Hello")
.header("server", "keulkeul")
.entity("Ceci est le message du coprs de la rponse")
.build();
}
}
Un contenu String
dans le coprs
Finalisation en appelant
la mthode build()
JAX-RS - M. Baron - Page 63
Response
Exemple : Code de retour avec erreur dans la rponse
@Path("/contentbooks")
public class BookResource {
...
@Path("response")
@GET
public Response getBooks() {
return Response
.serverError()
.build();
}
}
BookResource.java du projet
keulkeul.blogspot.com
LibraryContentRestWebService
Response
Exemple : Retourner une URI lors de la cration dune
ressource
BookResource.java du projet
LibraryContentRestWebService
keulkeul.blogspot.com
@Path("/contentbooks")
public class BookResource {
...
@Consumes("application/xml")
@POST
@Path("response")
public Response createBooks(Book newBook, @Context UriInfo uri) {
URI absolutePath = uri.getAbsolutePath();
return Response.created(absolutePath).build();
}
}
UriBuilder
La classe utilitaire UriBuilder permet de construire des URIs
complexes
Possibilit de construire des URIs avec UriBuilder via
UriInfo (voir @Context) o toutes URIs seront relatives au chemin
de la requte
From scratch qui permet de construire une nouvelle URI
UriBuilder
Le principe dutilisation de la classe utilitaire UriBuilder est
identique ResponseBuilder
Les principales mthodes
URI build(Object values) : construit une URI partir dune liste de
valeurs pour les Template Parameters
keulkeul.blogspot.com
paramtres de requte
UriBuilder
Exemple : Construire une URI partir de la requte et la
retourner lors de la cration dune ressource
BookResource.java du projet
keulkeul.blogspot.com
LibraryContentRestWebService
@Path("/contentbooks")
public class BookResource {
...
@Consumes("application/xml")
@POST
@Path("uribuilder1")
public Response createBooksFromURI(Book newBook, @Context UriInfo uri) {
URI absolutePath = uri
.getAbsolutePathBuilder()
.queryParam("param1", newBook.getName())
.path(newBook.getIsbn())
.build();
return Response.created(absolutePath).build();
}
}
Ajouter un paramtre
UriBuilder
Exemple : Construire une URI et la retourner lors de la
cration dune ressource
BookResource.java du projet
keulkeul.blogspot.com
LibraryContentRestWebService
@Path("/contentbooks")
public class BookResource {
...
@Consumes("application/xml")
@POST
@Path("uribuilder2")
public Response createURIBooks(Book newBook, @Context UriInfo uri) {
URI build = UriBuilder
.fromUri("http://www.mylocalhost")
.path("path1")
BookResource.java du projet
.path("path2")
.build();
LibraryContentRestWebService
return Response.created(build).build();
}
Dploiement
Les applications JAX-RS sont construites et dployes sous le
format dune application Web Java (WAR)
La configuration de JAX-RS dclarer les classes ressources
dans le fichier de dploiement (web.xml)
Deux types de configuration sont autorises
web.xml pointe sur une sous classe dApplication
web.xml pointe sur une Servlet fournie par limplmentation JAX-RS
keulkeul.blogspot.com
Dploiement
Exemple : Dclaration des classes ressources via la Servlet
fournie par limplmentation de JERSEY
keulkeul.blogspot.com
web.xml du projet
HelloWorldRestWebService
Dploiement
Exemple : Dclaration des classes ressources via Application
keulkeul.blogspot.com
LibraryRestWebServiceApplication
du projet
LibraryRestWebService
web.xml du projet
LibraryRestWebService
Usages
keulkeul.blogspot.com
HelloWorldResource.java du projet
HelloWorldRestWebServiceFromJavaSE
keulkeul.blogspot.com
HelloWorldRestWebServiceApplication.java du projet
HelloWorldRestWebServiceFromJavaSE
RuntimeDelegate rd = RuntimeDelegate.getInstance();
Adapter a = rd.createEndpoint(app, Adapter.class);
st = GrizzlyServerFactory.create(UriBuilder.fromUri("http://127.0.0.1:8084/").build(), a);
... // Partie cliente, dtaille dans la suite
keulkeul.blogspot.com
}
private static URI getBaseURI() {
return UriBuilder.fromUri("http://127.0.0.1:8084/").build();
}
HelloWorldResourceTest.java du projet
HelloWorldRestWebServiceFromJavaSE
Dveloppement Client
La spcification JAX-RS ne sintresse pas fournir une API
pour le traitement ct client
A voir du ct des implmentations JAX-RS si une API cliente
est fournie ou pas (JERSEY en propose une)
Possibilit galement dutiliser des bibliothques spcialises
dans lenvoi et la rception de requtes HTTP
keulkeul.blogspot.com
Configuration du client
c.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
Ou
c.setFollowRedirects(true);
Ou
keulkeul.blogspot.com
keulkeul.blogspot.com
keulkeul.blogspot.com
Dveloppement Client
Exemple : client pour rcuprer un livre (GET)
keulkeul.blogspot.com
BookResourceIntegrationTest.java du projet
LibraryRestWebService
Dveloppement Client
Exemple : client pour mettre jour un livre (PUT)
public class BookResourceIntegrationTest {
@Test
public void testUpdateContentBooksWithJAXBXMLService() throws IOException {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(getBaseURI());
WebResource path = service.path("contentbooks").path("jaxbxml");
Book current = new Book();
current.setIsbn("123-456-789");
current.setName("Harry Toper");
path.put(current);
}
keulkeul.blogspot.com
BookResourceIntegrationTest.java du projet
LibraryContentRestWebService
Dveloppement Client
Exemple : client manipulant un objet Response
public class BookResourceIntegrationTest {
@Test
public void testGetBooksService() {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(getBaseURI());
WebResource path = service.path("contentbooks").path("response");
ClientResponse response = path.get(ClientResponse.class);
MultivaluedMap<String, String> headers = response.getHeaders();
Assert.assertEquals("Bonjour", headers.getFirst("param1"));
Assert.assertEquals("Hello", headers.getFirst("param2"));
String entity = response.getEntity(String.class);
Assert.assertEquals("Ceci est le message du coprs de la rponse", entity);
Assert.assertEquals("Jetty(6.1.14)", headers.getFirst("server"));
keulkeul.blogspot.com
}
private static URI getBaseURI() {
return UriBuilder.fromUri("http://localhost:8088/librarycontentrestwebservice/").build();
}
}
BookResourceIntegrationTest.java du projet
LibraryContentRestWebService
keulkeul.blogspot.com
MessageBodyReader et MessageBodyWriter
Intgration de JAX-RS avec les EJBs
keulkeul.blogspot.com