II. Service Web avec JAX-RS▲
II-A. JAX-RS▲
JAX-RS est une spécification définie par Sun pour simplifier l'utilisation de Services Web RESTful en Java. Et le moins que l'on puisse dire est que cela est très réussi. Il est également possible d'utiliser JAX-RS comme une Servlet pour faire une page Web classique.
L'utilisation de JAX-RS se fait en quatre parties.
II-A-1. Installation▲
Le serveur Glassfish v2 fournit directement Jersey et ses dépendances. Jersey est le mécanisme gérant JAX-RS développé par Sun Microsystem, JBOSS va utiliser RestEasy. Il vous faut aussi l'API proprement dite de JAX-RS dans le ClassPath.
Il faut ensuite installer la Servlet de Jersey qui prendra en charge les requêtes. Cette servlet fait partie de la bibliothèque Jersey 1.0 montrée plus haut.
<servlet>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>
1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>
ServletAdaptor</servlet-name>
<url-pattern>
/myjax/*</url-pattern>
</servlet-mapping>
Si le context de la Web Application est « mywebapp », toutes les requêtes allant vers /mywebapp/myjax seront destinées à Jersey.
II-A-2. Tester GET▲
Créons donc une classe dans le package destiné à recevoir vos requêtes. Mon package s'appelle demo.myjax , et la classe EvenBondGetREST.
package
demo.myjax;
import
javax.ws.rs.GET;
import
javax.ws.rs.Path;
import
javax.ws.rs.core.Response;
import
javax.ws.rs.core.Response.Status;
/**
* First tests with JAX-RS
*
@author
Nicolas Zozol for Robusta Web Library Tutorial
*/
@Path
(
"/bond"
)//Full path is so /mywebapp/myjax/bond
public
class
EvenBondGetREST {
@GET
@Produces
(
"text/html"
)
public
Response getBond
(
){
Response r =
Response.status
(
Status.OK).entity
(
"<html><body>Bond, James Bond</body></html>"
).build
(
);
return
r;
}
}
Nous déployons la Web Application avec le serveur Glassfish (ou Tomcat), et lançons Firefox. Le port sera 8080. |
II-A-3. ResourceController fournit par Robusta▲
James Bond envoie une requête POST à notre ResourceController pour ajouter une donnée. Nous allons valider cette requête en vérifiant sommairement l'identification. Voici le code Ajax, fait à partir de prototype.js et robusta.js pour le traitement XML de la réponse.
<!--
POST /mywebapp/myjax/bond
Authorization : James Bond
<root><ennemy>Le Chiffre</ennemy></root>
-->
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
>
<html>
<head>
<title>
Test Post with Ajax</title>
<meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
>
<script
type
=
"text/javascript"
src
=
"/mywebapp/lib/js/prototype.js"
></script>
<script
type
=
"text/javascript"
src
=
"/mywebapp/lib/js/robusta.js"
></script>
</head>
<body>
<div
id
=
"message"
style
=
"background-color:yellow;font-weight:bold"
></div>
</body>
<script
type
=
"text/javascript"
>
var url ="/mywebapp/myjax/bond/";
var postBody="<root><ennemy>
Le Chiffre</ennemy></root>
";
new Ajax.Request(url, {
method: 'POST',
contentType :'application/xml;charset=UTF-8',
postBody : postBody,
requestHeaders:$H({Authorization:"James Bond"}),
onSuccess: function(transport) {
var result = robusta.VerySimpleXml.getValue(transport,"message");
$("message").update(result);
}
});
</script>
</html>
La requête Ajax arrive vers la fonction annotée par POST :
@Path
(
"/bond"
)//Full path is so /mywebapp/myjax/bond
public
class
EvenBondGetREST extends
JaxRsResourceController {
@POST
@Produces
(
"application/xml"
)
public
Response ajaxPost
(
String content) {
//Content corresponds to the postBody of the request
try
{
String userString =
getAuthorizationValue
(
);// The ResourceController finds the Authorization header of the request
if
(
userString.contains
(
"Bond"
)) {
//light authentication :)
String ennemy =
new
VsxSax
(
).getValue
(
content, "ennemy"
); // VsxSax signifie "VerySimpleXml, Sax implementation"
String message =
userString+
" has a new Ennemy :"
+
ennemy;
return
classicSuccess
(
message);
}
else
{
throw
new
UnauthorizedException
(
"User "
+
userString +
" is not allowed"
);
}
}
catch
(
Exception ex) {
return
classicFailure
(
ex);
}
}
}
//End of class
Le résultat est un succès :
Si toutefois un utilisateur perfide tentait de se connecter avec une mauvaise autorisation, une UnauthorizedException serait lancée, aussitôt 'catchée' et une réponse adéquate serait renvoyée. Cette « identification » n'est évidemment pas suffisante, et nous développerons une stratégie acceptable au chapitre « Sécurité »