REST + JPA avec Spring

Transcription

REST + JPA avec Spring
[email protected]
REST + JPA avec Spring
De nombreuses applications Web se présentent comme des formulaires HTML qui ne sont
que des vues permettant d’éditer le contenu d’une table d’une base de données stockée côté
serveur. Ce type d’application basique ne requiert pas de traitement complexe, ni côté client,
ni côté serveur. Dans ce cas, il est une architecture logicielle simple qui convient
parfaitement : l’architecture REST (REpresentational State Transfert). Le principe de REST
est de transférer entre un client et un serveur, une représentation d’une ressource
(ressource qui peut être un enregistrement dans une base de données par exemple). La
représentation d’une ressource qu’obtient un client (une structure de données XML par
exemple) est un état de cette ressource.
Matériel requis
-
Spring 3.0
Java 1.6
Eclipse avec le plug-in WTP (ici c’est Eclipse Galileo qui a été utilisé en version JEE
developper)
Apache-Tomcat 5 ou plus.
L’installation de Spring n’est pas requise car les fichiers sources de l’application côté
serveur, récupérables à l’adresse ci-dessous, contiennent aussi toutes les librairies de
Spring pour ce projet :
http://perso.efrei.fr/~charroux/REST+JPA+Spring/serveur/
Les sources et les librairies côté client sont accessibles à l’adresse suivante :
http://perso.efrei.fr/~charroux/REST+JPA+Spring/client/
Exemple d’une application REST
Concrètement REST s’appuie couramment sur le protocole HTTP et en exploite toutes les
méthodes POST, GET, PUT, DELETE…, les ressources étant associées à des URL.
Ci-dessous, voici un exemple sommaire d’utilisation de REST (côté client). Pour créer une
nouvelle ressource sur le serveur (un enregistrement dans une base de données par
exmemple), il faut envoyer via la méthode POST l’URL suivante (où n’importe quelle URL qui
a un sens pour celui qui utilise l’application) :
// création d'une nouvelle ressource
String url = "http://localhost:8080/REST_JPA_Spring/entities";
Méthode POST
Pour obtenir une liste de ressources (ou plutôt leurs états) on envoie au serveur la même
URL mais via la méthode GET :
// récupération d’une liste de ressources
url = "http://localhost:8080/REST_JPA_Spring/entities";
Méthode GET
Page 1
[email protected]
On peut aussi récupérer l’état d’une ressource particulière si on connait son identifiant via la
méthode GET :
// récupération d'une ressource (celle d’identifiant 1)
url = "http://localhost:8080/REST_JPA_Spring/entities/1";
Méthode GET
La suppression de la ressource d’identifiant 1 se fait avec un DELETE :
// suppression d'une ressource (celle d’identifiant 1)
url = "http://localhost:8080/REST_JPA_Spring/entities/1";
Méthode DELETE
REST avec Spring
Spring offre un moyen simple de développer une application REST. Côté client, on dispose
de la classe RestTemplate qui offre toutes les méthodes POST, GET… Par exemple pour
créer une nouvelle ressource, cette classe s’utilise de la façon suivante :
// création d'une nouvelle ressource
String url = "http://localhost:8080/REST_JPA_Spring/entities";
RestTemplate restTemplate = new RestTemplate();
MonEntity monEntity = new MonEntity();
URI uri = restTemplate.postForLocation(url, monEntity);
Où MonEntity représente la ressource à créer. La méthode postForLocation retourne
l’URL de la nouvelle ressource après qu’elle ait été créée.
Côté serveur, c’est tout aussi basique car un simple Controller, au sens MVC du terme, suffit
pour traiter les requêtes :
@Controller
@RequestMapping("/entities")
public class MonEntityController {
@RequestMapping(method = RequestMethod.POST)
public View createMonEntity(@RequestBody MonEntity monEntity) {
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
entityManager.persist(monEntity);
tx.commit();
return new RedirectView("/entities/" + monEntity.getId());
}
// …
}
On voit que la création de la ressource est ici réalisée en base de donnés via Java
Persistence Api (JPA) grâce à l’instruction entityManager.persist(monEntity), et que la
méthode createMonEntity retourne l’URL de la nouvelle ressource créée.
Page 2
[email protected]
Création d’un projet côté serveur
Avant tout, il faut télécharger Apache/Tomcat à partir du lien suivant :
http://tomcat.apache.org/
Le téléchargement de la version Core et sa décompression sur votre machine suffit.
Création d’un projet web de type Dynamic Web Project sous Eclipse :
Où, Traget Runtime a été initialisée avec Apache Tomcat en cliquant sur New et en
sélectionnant le répertoire où est installé Apache Tomcat sur votre machine :
Page 3
[email protected]
Ajout des fichiers sources et des librairies
Décompressez le fichier téléchargé correspondant au serveur (voir le début de cet article)
dans le répertoire du projet. Mettez à jour Eclipse via un F5 sur le projet. Celui-ci doit à
présent se présenter comme suit :
Où MonEntityController du package « presentation » est le Controller qui reçoit les
requêtes HTTP.
MonEntity du package « metier » est une classe persistante pour JPA, et représente la
ressource à gérer. C’est le fichier persistence.xml qui définit le paramétrage de JPA.
La configuration de Spring se fait dans deux fichiers (do-servlet.xml et appliContext.xml). On
y trouve notamment la déclaration du Controller :
<bean id="monEntityController" class="presentation.MonEntityController">
<constructor-arg ref="entityManagerFactory"/>
</bean>
Mais aussi toute la gestion des formats de données qui transitent via HTTP. Spring est ici
d’une grande utilité car il prend en charge automatiquement les conversions de XML, qui est
utilisé par REST, vers Java, et vice versa. Pour cela Spring délègue les conversions à JAXB
(l’API qui permet de manipuler de l’XML en Java) :
<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound name="metier.MonEntity"/>
<oxm:class-to-be-bound name="presentation.MesEntities"/>
</oxm:jaxb2-marshaller>
Page 4
[email protected]
Où on voit que la classe metier.MonEntity va permettre de manipuler les données XML
retournée par les requêtes HTTP en Java. Pour autoriser cela, il faut que le code de la
classe MonEntity soit annoté avec XmlRootElement et XmlElement comme dans :
@Entity
@XmlRootElement
public class MonEntity {
private long id;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlElement
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
C’est grâce à ces conversions qu’il est possible d’envoyer à partir du client des objets du
type MonEntity vers le serveur comme dans :
// création d'une nouvelle ressource
String url = "http://localhost:8080/REST_JPA_Spring/entities";
RestTemplate restTemplate = new RestTemplate();
MonEntity monEntity = new MonEntity();
URI uri = restTemplate.postForLocation(url, monEntity);
Lancement de l’application
Ici, c’est la base de données HSQLDB qui est utilisée. Elle se lance de la façon suivante à
partir du répertoire (à modifier pour l’adapter à votre cas) où sont stockées les librairies :
Un utilitaire pour inspecter la base peut aussi être démarré :
Page 5
[email protected]
Attention ! Pour accéder à la base, il faut s’y connecter via le serveur :
Le pilotage d’Apache-Tomcat se fait dans l’onglet serveur (accessible via Windows-> Show
view -> Other… -> Servers) :
Où il faut ajouter Tomcat, et ne pas oublier d’y insérer le projet (clic droit sur Tomcat -> menu
Add and remove…). Il ne reste plus qu’à démarrer le serveur.
Page 6
[email protected]
Création d’un projet côté client
REST peut utiliser côté client une application web écrite en HTML et Java Script. JSON est
alors souvent utilisé pour manipuler les structures de données de REST. Cependant, c’est
un client Java qui est utilisé ici. Il faut alors créer un projet sous Eclipse pour le client. Un
simple projet Java suffit :
Il faut ensuite y décompresser les fichiers téléchargés au début de ce tutorial. Le projet sous
Eclipse doit alors de présenter de la façon suivante :
Où les libraires de Spring ont été ajoutées au projet (clic doit sur le projet -> properties) :
Page 7
[email protected]
Pour faciliter le codage de l’application cliente et pour qu’Eclipse ne cherche pas den vain le
code de la classe MonEntity, on peut donner au projet client un accès à celui du serveur :
La classe Main contient le programme Java qu’il suffit de lancer pour exécuter l’application.
Page 8
[email protected]
Conclusion
Ce qui fait le succès actuel de REST est sa simplicité et sa facilité de programmation.
Comme cette architecture est basée sur des URL et les méthodes de HTTP, les applications
côté client et serveur sont faiblement couplés et elles peuvent donc évoluer séparément. De
plus, l’état d’une ressource étant transmis chez le client, il n’y a plus alors consommation de
moyens informatique sur le serveur. Le client peut conserver un état le temps de le traiter car
les ressources étant persistantes sur le serveur, il pourra les retrouver.
Contrairement aux applications de type Remote Procedure Call qui utilisent des verbes et
des noms pour définir les méthodes à utiliser ainsi que leurs arguments, REST offre une
interface standard : des URL et les méthodes de HTTP pour tout faire. Une application REST
peut alors exploiter pleinement HTTP qui sait gérer l’authentification, la gestion de caches
ainsi que la négociation de type de contenu, là où il faut définir ces services dans une
application de type RPC.
Pour être conforme aux principes de REST, une application doit respecter certaines
contraintes. La plus importante étant une communication sans état : le serveur ne doit pas
maintenir dans des données temporaires de session le contexte propre à un client entre
deux appels. Mais attention, cela ne veut pas dire forcément stockage sans état car il est
possible de conserver sur le serveur sous forme de données persistantes associées à des
URL des états propres à un client.
Parmi les critiques de REST la plus importante est que le client doit découvrir au fil de l’eau,
avec les réponses qu’il reçoit (des structures de données XML), ce qu’il peut en faire. Pas
de problème tant qu’on connait a priori le format de ces structures (comme c’est le cas dans
l’application ci-dessus puisque côte client ET côté serveur utilisent la même classe
MonEntity). Pas de problème non plus si on dispose côté client d’un humain pour interpréter
les données. Mais les applications d’entreprise, notamment avec le Business Process
Management tendent à exécuter automatique des applications avec des moteurs de
workflow. Dans ce cas, les Web Services traditionnels avec les services qui s’auto-décrivent
en WSDL restent incontournables.
Page 9

Documents pareils