0% ont trouvé ce document utile (0 vote)
10 vues592 pages

Introduction aux Web Services SOAP et REST

Transféré par

hsan.isetsf
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
10 vues592 pages

Introduction aux Web Services SOAP et REST

Transféré par

hsan.isetsf
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd

Web Services

SOAP et
RESTful

Mohamed Youssfi :
med@[Link] ENSET,
Université Hassan II Mohammedia
med@[Link]
Exigences d’un projet
informatique
 Exigences fonctionnelles:
◦ Une application est créée pour répondre , tout
d’abord, aux besoins fonctionnels des
entreprises.
 Exigences Techniques :
◦ Les performances:
 Temps de réponse
 Haute disponibilité et tolérance aux pannes
 Eviter le problème de montée en charge
◦ La maintenance:
 Une application doit évoluer dans le temps.
 Doit être fermée à la modification et ouverte à l’extension
◦ Sécurité
◦ Portabilité
◦ Distribution
◦ Capacité de communiquer avec d’autres applications distantes.
◦ Capacité de fournir le service à différents type de clients (Desk TOP,
Mobile, SMS, http…)
◦ …..
◦ Coût du logiciel
2
med@[Link]
Constat
 Ilest très difficile de développer un système
logiciel qui respecte ces exigences sans utiliser
l’expérience des autres :
◦ Serveur d’application JEE:
 JBOSS,Web Sphere,
 GlassFish,Tomcat,
 …
◦ Framework pour l’Inversion de contrôle:
 Spring (Conteneur léger)
 EJB (Conteneur lourd)
◦ Frameworks :
 Mapping objet relationnel (ORM ) : JPA, Hibernate,Toplink, …
 Applications Web : Struts, JSF, SpringMVC
 ….
◦ Middlewares :
 RMI, CORBA : Applications distribuées
 JAXWS pour Web services SOAP
 JAXRS pour les Web services RESTful
 JMS : Communication asynchrone entre les application
 …

med@[Link]
Vision globale d’une architectures
Distribuées

SGB
D Entreprise 1 Entreprise 2 SGBD

Serveur Serveur d’application

d’application Couche DAO

Couche DAO

Couche Couche métier


métier

Couche web Couche - TTP


-
Service
Client HTTP
MiddleWares
:
- RMI
- CORBA H
TCP/IP UDP t
Couche web
Couc
he
Servi
ce
Middl
eWar
es :
- RMI HTTP
- CORBA
- JMS
-Web Client
Servi HTTP
ces

m
e
d
@
y
o
u
s
s
f
i
.
n
e
Architecture J2EE
Client Java RMI,
Serveur d’application J2EE
JM

Web Spring ou EJB Services de


Container Container l’infrastructure
Client HTTP (Couche (Couche
HTML Jax WS, Jax RS
http Web) Métier)
Servlet, JSP Jersey, CXF,
SOA AXIS
Client Spring MVC, JSF
P JTA
SOAP XML
Java, .Net, PHP, Composan JNDI
Cobol Servic ts ….
e SOAP Métier
AXIS, CXF (Traitemen
HTTP ts)
JPA
Client HTTP JSON, XML,
.. Servic Hiberna
Mobile, JQuery, e te JDBC
Flash
RESTf
Entity
ul
Jersey, Entity
CXF
SGBD
Data
Base
Web services
SOAP
WSD
L
med@[Link]
Introduction aux web services
 Les Web Services sont des composants web
basés sur Internet (HTTP ) qui exécutent des
tâches précises et qui respectent un format
spécifique (XML).
 Ils permettent aux applications de faire appel
à des fonctionnalités à distance en simplifiant
ainsi l’échange de données.
 Les Web Services permettent aux applications de
dialoguer à travers le réseau, indépendamment
de
◦ leur plate-forme d’exécution
◦ et de leur langage d'implémentation.
 Ils s’inscrivent dans la continuité d'initiatives telles
que
◦ CORBA (Common Object Request Broker
Architecture, de l'OMG) en apportant toutefois
une réponse plus simple, s’appuyant sur des
technologies et standards reconnus et
maintenant acceptés de tous.
med@[Link]
LE PROTOCOLE HTTP
 HTTP :HyperText Tranfert Protocol
◦ Protocole qui permet au client de récupérer des documents
du serveur
◦ Ces documents peuvent être statiques (contenu qui ne
change pas : HTML, PDF, Image, etc..) ou dynamiques (
Contenu généré dynamiquement au moment de la
requête : PHP, JSP, ASP…)
◦ Ce protocole permet également de soumissionner les
formulaires
 Fonctionnement (très simple en HTTP/1.0)
◦ Le client se connecte au serveur (Créer une socket)
◦ Le client demande au serveur un document : Requête HTTP
◦ Le serveur renvoi au client le document (status=200) ou
d’une erreur (status=404 quand le document n’existe
pas)
◦ Déconnexion
med@[Link]
Connexion

Client HTTP Serveur Web


Connexion
:Socket :ServerSocket
IPS= GET /[Link]
Port=80 Post /[Link] port=80
Réponse HTTP accept()

Status=200
Déconnexion :Socket
[Link] IPC=…. [Link]
port=…
.

med@[Link]
Méthodes du protocole HTTP
 Une requête HTTP peut être envoyée en
utilisant les méthodes suivantes:
◦ GET : Pour récupérer le contenu d’un document
◦ POST : Pour soumissionner des formulaires
(Envoyer, dans la requête, des données saisies
par l’utilisateur )
◦ PUT pour envoyer un fichier du client vers le
serveur
◦ DELETE permet de demander au serveur de
supprimer un document.
◦ HEAD permet de récupérer les informations
sur un document (Type, Capacité, Date de
dernière modification etc…)
med@[Link]
Le client envoie la requête : Méthode POST

Entête de la requête

Post /Nom_Script HTTP/1.0


Accept: text/html
Accept-Language :
fr User-Agent :
Mozilla/4.0
*** saut de ligne ***
login=Value1& pass=Value2
& Var3=Value3

corps de la requête
med@[Link]
Le client envoie la requête : Méthode GET

Entête de la requête

GET /Nom_Script?login=val1&pass=val2&…. HTTP/1.0


Accept: text/html
Accept-Language : fr
User-Agent : Mozilla/4.0

corps de la requête est vide

med@[Link]
Le Serveur retourne la réponse :

Entête de la réponse

HTTP/1.0 200 OK
Ligne de
Date : Wed, 05Feb02 [Link] GMT
Status Date du
Server : Apache/1.3.24
serveur Nom
Last-Modified : Wed 02Oct01
du Serveur
[Link]GMT Content-Type : Text/html
Dernière
Content-legnth : 4205
modification
*** saut de ligne ***
Type de
<HTML><HEAD>
contenu
….
Sa taille
</BODY></HTML>

Le fichier que le client


va afficher
corps de la réponse
med@you .net
L’idée des Web Services
Clie Requête HTTP Serveur
nt
HTTP
<?xml version="1.0"
PHP encoding="UTF-8"?> BanqueSer
<Envelope>
<Header/>
vice
.ne <Body>
<conversion> +conversion(double mt):double
t <montant>12</montant> +Compte getCompte()
</conversion>
+List<Compte> getComptes()
jav

a
Cobo </Body>
Compte
</ JaxW
l Envelope
>
-code : int
S -solde: double
Réponse
HTTP JaxB
<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<Body>
<conversionResponse>
<return>132</return>
</conversionResponse>
</Body>
</Envelope>
Requête SOAP avec POST

Entête de la requête

Post /Nom_Script
HTTP/1.0 Accept:
application/xml Accept-
Language : fr

*** saut de ligne ***

corps de la requête SOAP


med@[Link]
Réponse SOAP : Entête de la réponse
HTTP/1.0 200 OK
Date :Wed, 05Feb02 [Link] GMT
Server :
Apache/1.3.24
Mime-Version 1.0
Last-Modified :Wed 02Oct01
[Link]GMT Content-Type
:Text/xml
Content-legnth : 4205
*** saut de ligne ***

corps de la réponse
med@[Link]
Concepts des web services
 Le concept des Web Services s’articule actuellement
autour des trois concepts suivants :
◦ SOAP (Simple Object Access Protocol)
 est un protocole d'échange inter-applications indépendant de
toute plate-forme, basé sur le langage XML.
 Un appel de service SOAP est un flux ASCII encadré dans des
balises XML et transporté dans le protocole HTTP.

◦ WSDL (Web Services Description Language)


 donne la description au format XML des Web Services en précisant
les méthodes pouvant être invoquées, leurs signatures et le point
d’accès (URL, port, etc..).
 C’est, en quelque sorte, l’équivalent du langage IDL pour la
programmation distribuée CORBA.

◦ UDDI (Universal Description, Discovery and Integration)


 normalise une solution d’annuaire distribué de Web Services,
permettant à la fois la publication et l'exploration (recherche) de
Web Services.
 UDDI se comporte lui-même comme un Web service dont les
méthodes sont appelées via le protocole SOAP.
med@[Link]
Cycle de vie d’utilisation
Annuaire
UDDI
2 : J’ai trouvé! Voici le
serveur hébergeant ce
recherche un

service web
service WEB

Contrat
SOAP
3 : Quel est le format
d’appel du service que
1 : Je

tu proposes?

4 :Voici mon contrat


(WSDL) XML
Serve
Client ur
XML

5 : J’ai compris comment


invoquer ton service et je
t’envoie un document XML
représentant ma requête
XML
6 : J’ai exécuté ta
requêtemeedt@jeyoutses
[Link] le résultat
SOAP
 SOAP est un protocole d'invocation de méthodes sur
des services distants. Basé sur XML,
 SOAP a pour principal objectif d'assurer la
communication entre machines.
 Le protocole permet d'appeler une méthode RPC et
d'envoyer des messages aux machines distantes via
un protocole de transport ( HTTP ).
 Ce protocole est très bien adapté à l'utilisation des
services Web, car il permet de fournir au client une
grande quantité d'informations récupérées sur un
réseau de serveurs tiers, voyez :

med@youssfi.
Structure d'un message
SOAP

<?xml version="1.0" encoding="utf-8"?>


<soap:Envelope
xmlns:soap="[Link]
soap:encodingStyle="[Link]
g">
<soap:Header>
<!-- en-tête -->
</soap:Header>
<soap:Body>
<!-- corps -->
</soap:Body>
</soap:Envelope> med@youssfi.
Structure d’un message
SOAP
 SOAP envelope (enveloppe)
◦ Est l'élément de base du message SOAP.
◦ L'enveloppe contient la spécification des espaces
de désignation (namespace) et du codage de
données.
 SOAP header
◦ (entête) est une partie facultative qui permet
d'ajouter des fonctionnalités à un message SOAP
de manière décentralisée sans agrément entre
les parties qui communiquent.
◦ L'entête est utile surtout, quand le message doit
être traité par plusieurs intermédiaires.
 SOAP body (corps) est un container pour les
informations mandataires à l'intention du
récepteur du message, il contient les méthodes
et les paramètres qui seront exécutés par le
destinataire final.
 SOAP fault (erreur) est un élément facultatif
défini dans le corps SOAP et qui est utilisé pour
reporter les erreurs.

med@[Link]
Mise en œuvre
des web services
avec JAX-WS

med@[Link]
JAX-WS
 JAX-WS est la nouvelle appellation de JAX-RPC (Java API for XML
Based RPC) qui permet de développer très simplement des
services web en Java.
 JAX-WS fournit un ensemble d'annotations pour mapper la
correspondance Java- WSDL. Il suffit pour cela d'annoter
directement les classes Java qui vont représenter le service web.
 Dans l'exemple ci-dessous, une classe Java utilise des annotations
JAX-WS qui vont permettre par la suite de générer le document
WSDL. Le document WSDL est auto-généré par le serveur
d'application au moment du déploiement :
@WebService(serviceName="BanqueW
S") public class BanqueService {
@WebMethod(operationName="ConversionEuroToDh")
public double conversion(@WebParam(name="montant")double
mt){ return mt*11;
}
@WebMethod
public String test(){ return "Test";
} @WebMethod
public Compte getCompte(){ return new Compte (1,7000);

} @WebMethod
public List<Compte> getComptes(){
List<Compte> cptes=new
ArrayList<Compte>();
[Link] (new Compte (1,7000)); [Link] (new Compte
(2,9000)); return cptes;
}}
med@[Link]
JAX-WS / JAXB
 JAX-WS s'appuie sur l'API JAXB 2.0 pour tout ce qui
concerne la correspondance entre document XML et
objets Java.
 JAXB 2.0 permet de mapper des objets Java dans un
document XML et vice versa.
 Il permet aussi de générer des classes Java à partir un
schéma XML et vice et versa.
Principe de JAXB
 Le mapping d'un document XML à des objets (unmarshal)

•La création d'un document XML à partir d'objets


(marshal)
med@[Link]
Générer XML à partir des objet java avec JAXB
package ws;
import [Link]; import
[Link]; import [Link].*;
public class Banque {
public static void main(String[] args) throws Exception {
JAXBContext
context=[Link]([Link]); Marshaller
marshaller=[Link]();
[Link](Marshaller.JAXB_FORMATTED_OUTPUT,
true); Compte cp=new Compte(1,8000,new Date());
[Link](cp,new File("[Link]"));
}}

package ws; Fichier XML Généré : [Link]


import [Link];
<?xml version="1.0" encoding="UTF-8"?>
import <compte>
[Link].*; <code>1</code>
@XmlRootElement <dateCreation>
public class Compte {
2014-01-16T[Link].960Z
private int code;
private float solde;
</dateCreation>
<solde>8000.0</solde>
private Date dateCreation;
</compte>
// Constructeur sans paramètre
// Constructeur avec paramètres
// Getters et Setters
} med@[Link]
Générer des objets java à partir des
données XML
package ws;
import
[Link].*;
import [Link].*;
public class Banque2 {
public static void main(String[] args) throws Exception {
JAXBContext jc=[Link]([Link]);
Unmarshaller unmarshaller=[Link]();
Compte cp=(Compte) [Link](new
File("[Link]")); [Link]([Link]()
+"-"+[Link]()+"- "+[Link]());
}
}

Fichier XML Source : [Link]


<?xml version="1.0" encoding="UTF-8"?>
<compte>
<code>1</code>
<dateCreation>
2014-01-16T[Link].960Z
</dateCreation>
<solde>8000.0</solde>
</compte>
med@[Link]
Générer un schéma XML à partir d’une classe avec
JaxB
package ws;
import
[Link].*;
import [Link].*;import
[Link]; import
[Link];
public class Banque {
public static void main(String[] args) throws Exception {
JAXBContext
context=[Link]([Link]);
[Link](new SchemaOutputResolver() {
@Override
public Result createOutput(String namespaceUri, String
suggestedFileName) throws IOException {
File f=new File("[Link]");
StreamResult result=new
StreamResult(f);
[Link]([Link]());
return result;
}
});}}

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>


<xs:schema version="1.0" xmlns:xs="[Link]
<xs:element name="compte" type="compte"/>
<xs:complexType name="compte">
<xs:sequence>
<xs:element name="code" type="xs:int"/>
<xs:element name="dateCreation" type="xs:dateTime" minOccurs="0"/>
<xs:element name="solde" type="xs:float"/>
</xs:sequence>
</xs:complexType>
</xs:schema> med@youssfi.
Génération des classes à partir d’un
schéma XML
 Pour permettre l'utilisation et la manipulation d'un
document XML, JAXB propose de générer un ensemble de
classes à partir du schéma XML du document.

•L'implémentation de référence fournit l'outil xjc pour


générer les classes à partir d'un schéma XML.
•L'utilisation la plus simple de l'outil xjc est de lui fournir
simplement le fichier qui contient le schéma XML du
document à utiliser.
med@youssfi.
Classes générées par XJC
 L’outil XJC génère deux classes :
◦ [Link] qui correspond au type
complexe Compte dans le schéma
xml.
◦ [Link] : une fabrique qui
permet de créer des objets de type
Compte.
med@[Link]
Quelques annotations JAXB
Annotation Description
@XmlRootEleme Associer une classe ou une énumération à
un élément XML
nt @XmlSchema Associer un espace de nommage à un package

@XmlTransient Marquer une entité pour ne pas être


mappée dans le document XML

@XmlAttribute Convertir une propriété en un attribut


dans le document XML

@XmlElement Convertir une propriété en un élément


dans le document XML

@XmlAccessorTy Préciser comment un champ ou une


propriété est sérialisé

pe @XmlNs Associer un prefixe d'un espace de


nommage à un URI

med@[Link]
Comment développer un web service
JAW-WS
1. Créer le service Web
◦ Développer le web service
◦ Déployer le web service
 Un serveur HTTP
 Un Conteneur WS ( JaxWS, AXIS, CXF, etc…)
2. Tester le web service avec un analyseur
SOAP
◦ SoapUI,
◦ Oxygen, etc…
3. Créer les clients :
◦ Un client Java
◦ Un client .Net
◦ Un client PHP
med@[Link]
Application
 Créer un web service java en
utilisant JaxWS qui permet de :
◦ Convertir un montant de l’auro en DH
◦ Consulter un compte sachant son code
◦ Consulter une liste de comptes
 Tester le web service avec un
analyseur SOAP
 Créer un client Java
 Créer un client .Net
 Créer un client PHP

med@[Link]
Architectur
e1 Serveur JAXWS
Client SOAP (Java, .Net, PHP) BanqueService
+conversion(double mt):double
+Compte getCompte()
Client +List<Compte> getComptes()
3 4
1 6
2
STUB Compte
SOA
SKELETO -code : int
P N -solde: double
5
1
Le client demande au stub de faire appel à la méthode conversion(12)
2
Le Stub se connecte au Skeleton et lui envoie une requête SOAP
3
Le Skeleton fait appel à la méthode du web service
4
Le web service retourne le résultat au Skeleton
5
Le Skeleton envoie le résultat dans une la réponse SOAP au Stub
6
Le Stub fournie lé résultat au client med@[Link]
Développer le web service avec
JAX-WS
 Outils à installer :
◦ JDK1.7
◦ Editeur java : Eclipse.
 Créerun projet java en utilisant JDK1.7 comme
compilateur et environnement d’exécution java.
◦ Structure du projet :
med@[Link]
Implémentation de la classe
Compte
package metier;
import
[Link];
import
[Link];
import
[Link];
@XmlRootElement
@XmlAccessorType([Link])
public class Compte {
private Long code;
private double solde; @XmlTransient
private Date dateCreation;
// Constructeur sans paramètre et avec paramètre
// Getters et setters

}
Implémentation du web service
package ws;
import [Link].*;
import [Link].*;
import
[Link];
@WebService(serviceName="BanqueWS")
public class BanqueService {
@WebMethod(operationName="ConversionEuroToDh")
public double conversion(@WebParam(name="montant")double
mt){ return mt*11;
}
@WebMethod
public Compte getCompte(@WebParam(name="code")Long code)
{ return new Compte (code,7000,new Date());
}
@WebMethod
public List<Compte> getComptes(){
List<Compte> cptes=new
ArrayList<Compte>();
[Link] (new Compte (1L,7000,new
Date())); [Link] (new Compte
(2L,7000,new Date())); return cptes;
}}
med@[Link]
Simple Serveur JAX WS
import
[Link];
import [Link];
public class ServeurJWS {
public static void main(String[] args) {
String url="[Link]
[Link](url, new
BanqueService());
[Link](url);
}
}

Exécution du serveur Java

med@youssfi.
Analyser le WSDL
 Pour Visualiser le WSDL, vous pouvez
utiliser un navigateur web

med@[Link]
Structure du WSDL
 Un document WSDL se compose d'un ensemble d'éléments
décrivant les types de données utilisés par le service, les
messages que le service peut recevoir, ainsi que les liaisons
SOAP associées à chaque message.
 Le schéma suivant illustre la structure du langage WSDL qui
est un document XML, en décrivant les relations entre les
sections constituant un document WSDL.

med@[Link]
Structure du WSDL
 Un fichier WSDL contient donc sept éléments.
◦ Types : fournit la définition de types de
données utilisés pour décrire les messages
échangés.
◦ Messages : représente une définition
abstraire (noms et types) des données en
cours de transmission.
◦ PortTypes : décrit un ensemble
d'opérations. Chaque opération a zéro ou
un message en entrée, zéro ou plusieurs
messages de sortie ou d'erreurs.
◦ Binding : spécifie une liaison entre un
<portType> et un protocole concret (SOAP,
HTTP...).
◦ Service : indique les adresses de port de chaque
liaison.
◦ Port : représente un point d'accès de
services défini par une adresse réseau et une
liaison.
◦ Opération : c'est la description d'une
action exposée dans le port.

med@[Link]
Structure du WSDL

med@[Link]
Elément Types

med@[Link]
XML Schema

med@youssfi.
XML Schema
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:tns="[Link] xmlns:xs="[Link]
version="1.0" targetNamespace="[Link]
<xs:element name="ConversionEuroToDh"
type="tns:ConversionEuroToDh"></xs:element>
<xs:element name="ConversionEuroToDhResponse"
type="tns:ConversionEuroToDhResponse"/>
<xs:element name="compte" type="tns:compte"></xs:element>
<xs:element name="getCompte" type="tns:getCompte"></xs:element>
<xs:element name="getCompteResponse"
type="tns:getCompteResponse"></xs:element>
<xs:element name="getComptes" type="tns:getComptes"></xs:element>
<xs:element name="getComptesResponse"
type="tns:getComptesResponse"></xs:element>
<xs:complexType name="ConversionEuroToDh">
<xs:sequence>
<xs:element name="montant" type="xs:double"></xs:element>
</xs:sequence>
</
xs:complexType>
<xs:complexType name="ConversionEuroToDhResponse">
<xs:sequence>
<xs:element name="return" type="xs:double"></xs:element>
</xs:sequence>
</
xs:complexType>
XML Schema
<xs:complexType name="getCompte">
<xs:sequence>
<xs:element name="code" type="xs:long" minOccurs="0"></xs:element>
</xs:sequence>
</
xs:complexType>
<xs:complexType name="getCompteResponse">
<xs:sequence>
<xs:element name="return" type="tns:compte" minOccurs="0"></xs:element>
</xs:sequence>
</
xs:complexType>
<xs:complexType name="compte">
<xs:sequence>
<xs:element name="code" type="xs:long" minOccurs="0"></xs:element>
<xs:element name="solde" type="xs:double"></xs:element>
</xs:sequence>
</
xs:complexType>
<xs:complexType name="getComptes">
<xs:sequence></xs:sequence>
</xs:complexType>
<xs:complexType name="getComptesResponse">
<xs:sequence>
<xs:element name="return" type="tns:compte" minOccurs="0"
maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
Elément message

<message name="getCompte">
<part name="parameters"
element="tns:getCompte"></part>
</message>
<message name="getCompteResponse">
<part name="parameters"
element="tns:getCompteResponse"></part>
</message>
med@[Link]
Elément portType

<portType
name="BanqueService">
<operation
name="getCompte">
<input wsam:Action="[Link]
message="tns:getCompte"></input>
<output wsam:Action="[Link]
message="tns:getCompteResponse"></output>
</operation>
<operation name="getComptes">
<input wsam:Action="[Link]
message="tns:getComptes"></input>
<output wsam:Action="[Link]
message="tns:getComptesResponse"></output>
</operation>
<operation name="ConversionEuroToDh">
…..
</operation>
</portType> med@youssfi.
Elément binding

<binding name="BanqueServicePortBinding" type="tns:BanqueService">


<soap:binding transport="[Link]
style="document"></soap:binding>
<operation name="getCompte">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal"></soap:body>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
<operation name="getComptes">
…..
</operation>
</binding> med@youssfi.
Elément service

<service name="BanqueWS">
<port name="BanqueServicePort"
binding="tns:BanqueServicePortBinding">
<soap:address location="[Link]
</port>
</service>
med@[Link]
Tester les méthodes du web
service avec un analyseur
SOAP : SoapUI
med@[Link]
Tester les méthodes du web
service avec un analyseur
SOAP : SoapUI
med@[Link]
Tester la méthode
conversion
Requête SOAP
 <soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ws="[Link]
<soapenv:Header/>
<soapenv:Body>
<ws:ConversionEuroToDh>
<montant>60</montant>
</ws:ConversionEuroToDh>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP
 <S:Envelope xmlns:S="[Link]
<S:Body>
<ns2:ConversionEuroToDhResponse xmlns:ns2="[Link]
<return>660.0</return>
</ns2:ConversionEuroToDhResponse>
</S:Body>
</S:Envelope>
med@[Link]
Tester la méthode getCompte
Requête SOAP
 <soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ws="[Link]
<soapenv:Header/>
<soapenv:Body>
<ws:getCompte>
<code>2</code>
</ws:getCompte>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP
 <S:Envelope xmlns:S="[Link]
<S:Body>
<ns2:getCompteResponse xmlns:ns2="[Link]
<return>
<code>2</code>
<solde>7000.0</solde>
</return>
</ns2:getCompteResponse>
</S:Body>
</S:Envelope>

med@[Link]
Tester la méthode getComptes
Requête SOAP
 <soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ws="[Link]
<soapenv:Header/>
<soapenv:Body>
<ws:getComptes/>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP
 <S:Envelope xmlns:S="[Link]
<S:Body>
<ns2:getComptesResponse xmlns:ns2="[Link]
<return>
<code>1</code>
<solde>7000.0</solde>
</return>
<return>
<code>2</code>
<solde>7000.0</solde>
</return>
</ns2:getComptesResponse>
</S:Body>
</S:Envelope> med@youssfi.
Client Java
 Créer un nouveau projet Java
 Générer un proxy
◦ SoapUI est l’un des outils qui peuvent
être utilisés pour générer les artefacts
client en utilisant différents Framework
(Axis, CXF, JaxWS, etc…)
◦ Le JDK fournit une commande simple qui
permet de générer un STUB JaxWS pour
l’accès à un web service. Cette commande
s’appelle wsimport.
◦ SoapUI a besoin de savoir le chemin
de cette commande
◦ Avec la commande File
>Preferences>Tools , vous pouvez
configurer le ce chemin comme le montre
la figure suivante :
med@[Link]
Préférence générale de
SoapUI
med@youssfi.
Générer le STUB JaxWS

med@[Link]
Fichiers Générés

med@[Link]
Client Java
import [Link];
Serveur
import
[Link];
import [Link]; Web
Service
import [Link];
public class ClientWS {
Skeleton
public static void main(String[] args) {
BanqueService stub=new
BanqueWS().getBanqueServicePort(); SOAP
[Link]("Conversion");
[Link]([Link](9000)); Stub
[Link]("Consulter un compte");
Compte cp=[Link](2L); Client
[Link]("Solde="+[Link]())
; [Link]("Liste des comptes");
Java
List<Compte> cptes=[Link]();
for(Compte c:cptes){
[Link]([Link]()+"- -"+[Link]());
}
}

}
Architecture
Client
SOAP Serveur
JAXWS

BanqueService
Client +conversion(double mt):double
+test():String

1 6 3 4
2
STUB SKELETO
SOA
N
P
5
1 Le client demande au stub de faire appel à la méthode conversion(12)
2 Le Stub se connecte au Skeleton et lui envoie une requête SOAP

3 Le Skeleton fait appel à la méthode du web service


4 Le web service retourne le résultat au Skeleton
5 Le Skeleton envoie le résultat dans une la réponse SOAP au Stub
6 Le Stub fournie lé résultat au client med@[Link]
Client
JSP Serveur
JAXWS

BanqueService
Web Container +conversion(double mt):double
:Tomcat +getCompte(int code):Compte
+getComptes():List<Compte>

3 4
2
[Link]
SOA SKELETON
P5
1 HTTP 6

Client HTTP

med@[Link]
Création d’un projet Web Dynamique basé sur
Tomcat 7

 Créer
un projet Web Dynamique basé sur
Tomcat 7
med@[Link]
Projet Web Dynamique

med@[Link]
Générer un proxy (Stub) pour le web
Service
 Fichier > Nouveau > Web Service
Client
med@[Link]
Génération du proxy
 Générer le proxy à partir du WSDL

med@[Link]
Fichier Générés
 Le proxy généré est basé sur AXIS

med@[Link]
Client JSP
<%@page import="[Link]"%>
<%
double montant=0; double resultat=0;
if([Link]("montant")!=null){
montant=[Link]([Link]("montan
t")); BanqueServiceProxy service=new
BanqueServiceProxy();
resultat=[Link](montant);
}
%>
<html><body>
<form action="[Link]">
Montant :<input type="text" name="montant" value="<%=montant%>">
<input type="submit" value="OK">
</form>
<%=montant %> en Euro est égale à <%=resultat %> en DH
</body></html>
med@[Link]
Client SOAP avec .Net
 En utilisant Visual Studio (2010),
Créer un projet C# de type
Console
med@[Link]
Générer Le Proxy client Soap

med@[Link]
Code C# du client Serveur
using System;
namespace ClientSOAP
{ Web
Service
class Program
{
static void Main(string[] args) Skeleton
{
[Link] stub =
SOAP
new
[Link]();
Stub
[Link]("-------- Conversion----------");
[Link]([Link](34));
Client .N
[Link]("-------- Consulter un Compte
--------------------------------------------------------------------------------------------- ")
; et
[Link] cp = [Link](2L);
[Link]("Solde=" + [Link]);
[Link]("-------- Liste des comptes
------------------------------------------------------------------------------------------ ")
;
[Link][] cptes =
[Link](); for (int i = 0; i < [Link];
i++)
{

[Link](cptes[i].code + "-----" + cptes[i].solde);


}
[Link]();
}
}
}

med@[Link]
Client Graphique .Net
Créer un nouveau Projet Visual
Studio de type Windows Forms
Application
med@[Link]
Générer à nouveau le proxy
SOAP
med@[Link]
Dessiner les composants
graphique de l’interface
Serveur

Web Service

Skeleton

SOAP

Stub

Client .Net

med@[Link]
Code C#
using System;using [Link]; using [Link];using
[Link]; using [Link];using [Link]; using [Link];using
[Link]; namespace ClientGraphiqueSOAP { Serveur
public partial class Form1 : Form {
private [Link]
Web
stub; public Form1() { Service
InitializeComponent();stub = new [Link]();

Skeleton
}
private void button1_Click(object sender, EventArgs e)
SOAP
{ double mt = [Link]([Link]);
double res = [Link](mt); Stub
[Link] = [Link]();
}
private void button2_Click(object sender, EventArgs Client .Net
e) { [Link][] cptes =
[Link]();
DataTable dt = new DataTable("comptes");
[Link]("CODE");
[Link]("SOLDE");
for (int i = 0; i < [Link]; i++) {
[Link](cptes[i].code,
cptes[i].solde);
}
[Link] = dt;
} }}

med@[Link]
Web Service Java et Client PHP
Serveur JAXWS

BanqueService
Serveur Web +conversion(double mt):double
Apache +getCompte(int code):Compte
+getComptes():List<Compte>

3 4
2
[Link]
SOA SKELETON
P5
1 HTTP 6

Client HTTP

med@[Link]
Exemple de Client SOAP PHP
<?php
$client = new SoapClient('[Link]
$param=new stdClass();
$param->montant=23;
$res=$client-> soapCall("conversionEuroDH",array($param));
//var_dump($res);
echo($res-
>return);
$param2=new stdClass();
$param2->arg0=2;
$res2=$client-> soapCall("getCompte",array($param2));
//var_dump($res2); echo("Code=".
$res2->return->code);
echo("<br/>Solde=".$res2->return->solde);
$res3=$client-> soapCall("getComptes",array());
//
var_dump($res3);
echo ("<hr/>");
foreach($res3->return as
$cpte){ echo("Code=".$cpte-
>code);
echo("<br/>Solde=".$cpte->solde);
echo("<br/>");
}
?>
med@[Link]
Configuration du plugin Eclipse PDT
 Après avoir installé Easy PHP ou Wamp Server (Apage, MySQL, PHP,
PhpMyAdmin)
 Window > preferences

med@[Link]
Projet PHP

med@[Link]
Projet PHP

med@[Link]
Nouvelle page PHP

med@[Link]
Code PHP

<?php
$montant=0;$resultat=0;
if (isset($_GET['montant'])){
$montant=$_GET['montant'];
$client = new SoapClient('[Link]
$param=new stdClass();
$param->montant=$montant;
$rep=$client-> soapCall("conversionEuroDH",array($param));
$resultat=$rep->return;
}
?>
<html>
<body>
<form action="[Link]">
Montant :<input type="text" name="montant" value="<?php
echo($montant)?>">
<input type="submit" value="OK">
</form>
<?php echo($montant)?> en Euro est égale à <?php echo($resultat)?> en DH
</body>
</html> med@[Link]
Un autre
exemple Client
SOAP PHP
<?php
$mt=0;
if(isset($_POST['action'])){
$action=$_POST['action'];
if($action=="OK"){
$mt=$_POST['montant'];
$client=new SoapClient("[Link]
$param=new stdClass();
$param->montant=$mt;
$rep=$client-> soapCall("conversionEuroToDh",array($param));
$res=$rep->return;
}
elseif($action=="listComptes"){
$client=new SoapClient("[Link]
$res2=$client soapCall("getComptes",array());
->
}
}

?>
med@[Link]
Suite de l’exemple du Client SOAP PHP
<html>
<body>
<form method="post" action="[Link]">
Montant:<input type="text" name="montant" value="<?php echo($mt)?>">
<input type="submit" value="OK" name="action">
<input type="submit" value="listComptes" name="action">
</form>

Rsultat:
<?php if (isset($res)){
echo($res);
}
?>
<?php if(isset($res2)){?>
<table border="1" width="80%">
<tr>
<th>CODE</th><th>SOLDE</th>
</tr>
<?php foreach($res2->return as $cp) {?>
<tr>
<td><?php echo($cp->code)?></td>
<td><?php echo($cp->solde)?></td>
</tr>
<?php }?>
</table>
<?php }?>
</body>
</html>
med@[Link]
Web Service dans une
application web J2EE basée
sur Spring
 On souhaite créer une application web J2EE
basée sur Spring qui permet de déployer un web
service qui permet de :
◦ Ajouter un compte
◦ Consulter un compte
◦ Consulter tous les comptes
◦ Effectuer un versement d’un montant dans un compte
◦ Effectuer un retrait d’un montant sur un compte
◦ Effectuer un virement d’un montant d’un compte vers un
autre
◦ Supprimer un compte
 Chaque compte est défini par le code, le solde
et la date création
 Les comptes seront stockés dans une base de
données MySQL
med@[Link]
Architectu SGBD

re
Web
Container Spring IOC
Container
dependenc
ies
ContextLoaderListner
Spring
SimpleJaxW JPATransaction EntityManag Jax
s Manager er WS
ServiceExport
er
FactoryBean
Jax RS
[Link] Couche Jacks
Métier Couche
Couche on
DAO
SOAP
IBanqMetier [Link]
BanqControll
er
IBanqueDAO

BanqueService
JPA
BanqMetierImpl
BanqDAOImpl Hiberna
DispatcherServ
let te JDBC
HTTP SOAP
HTML

Client
Client SOAP
HTTP
Installation du plugin :
spring tools pour eclipse

med@[Link]
Installation du plugin :
spring tools pour eclipse

med@[Link]
Création d’un projet
Spring
med@[Link]
Création d’un projet Spring

med@[Link]
[Link]
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
[Link]
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/[Link]</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-
class>[Link]</lis
tener- class>
</listener>

med@[Link]
[Link]
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>[Link]
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/[Link]
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

med@[Link]
>/WEB-INF/spring/[Link]
• Ce fichier est lu par ContextLoaderListener, au démarrage du
serveur .
• C’est un fichier dans lequel contexte de l’application sera construit
• ContextLoaderListener représente Spring IOC
• c’est donc un fichier pour l’injection des dépendances
• Pour le moment, il est vide

<?xml version="1.0" encoding="UTF-8"?>


<beans
xmlns="[Link]
beans"
xmlns:xsi="[Link]
instance"
xsi:schemaLocation="[Link]
c
hema/beans
[Link]
spring- [Link]">

<!-- Root Context: defines shared resources


visible to all other web components -->
</beans>
med@[Link]
>/WEB-INF/spring/appServlet/[Link]
• Ce fichier est lu par DispatcherServlet qui représente le controleur web de
l’application

<?xml version="1.0" encoding="UTF-8"?>


<beans:beans
xmlns="[Link]
xmlns:xsi="[Link]
xmlns:beans="[Link]
xmlns:context="[Link]
xsi:schemaLocation="[Link] [Link]
[Link] [Link] [Link]

[Link] [Link]

<!-- Enables the Spring MVC @Controller programming model -->


<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up
static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the
/WEB-INF/views directory -->
<beans:bean
class="[Link]">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="[Link]" />
</beans:beans>
med@[Link]
Un exemple de contrôleur Spring
MVC
package [Link];
import [Link].*;import [Link].*;import org.slf4j.*;import
[Link];
import [Link]; import
[Link]; import
[Link];
/** Handles requests for the application home page. */
@Controller
public class HomeController {
private static final Logger logger = [Link]([Link]);
/** Simply selects the home view to render by returning its name. */
@RequestMapping(value = "/", method = [Link])
public String home(Locale locale, Model model) {
[Link]("Welcome home! The client locale is {}.",
locale); Date date = new Date();
DateFormat dateFormat = [Link]([Link], [Link],
locale);
String formattedDate = [Link](date);
[Link]("serverTime", formattedDate );
return "home";
}
}
med@[Link]
Un exemple de vue JSP
<%@ taglib uri="[Link] prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1> Hello world! </h1>
<P> The time on the server is ${serverTime}. </P>
</body>
</html>

med@[Link]
Fonctionnement
Clien Tomcat
t
Lire [Link]
:ContextLoaderListne :DispatcherServlet
r
:HomeController
Instancier Lire
Lire
root-
Req [Link]
[Link]
HTTP Instancier
GET/
doGet(request,respo :[Link]
nse) instanci
er
home()
HTTP
M
od
el
A
nd
Vi
Rep e
w
instanci rendu
er
html

med@[Link]
Structure du projet

med@[Link]
Création des entités
package [Link];
import
[Link];
import [Link];
import [Link];
@XmlRootElement
public class Compte implements Serializable {
private Long code;
private double solde;
private Date
dateCreation;
// Getters et Setters
// Constructeurs
}
med@[Link]
Web Service
package [Link];
import
[Link].*;
import
[Link].*;
@WebService
public class BanqueService {
@WebMethod(operationName="conversionEuroToDH"
) public double conversion(double mt){
return mt*11;
}
@WebMethod
public Compte getCompte(@WebParam(name="code")Long code){
return new Compte(code,[Link]()*4000, new
Date());
}
@WebMethod
public List<Compte> getComptes(){
List<Compte> cptes=new
ArrayList<Compte>();
[Link] (new Compte(1L,[Link]()*4000, new
Date())); [Link] (new Compte(2L,[Link]()*4000,
new Date())); return cptes;
}
}
Déploiement du web service avec Spring
/WEB-INF/spring/[Link]

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
beans
[Link]
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="service" class="[Link]"></bean>
<bean class="[Link]">
<property name="baseAddress" value="[Link]
</bean>
</beans>

med@[Link]
Déploiement du projet
 Déployer le projet en utilisant
Tomcat7
 Démarrer le serveur Tomcat
med@[Link]
Tester le web service

med@youssfi.
Persistance des comptes avec JPA
Hibernate
med@[Link]
Maven Dependencies
<!-- Hibernate-->
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>[Link]</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-validator</artifactId>
<version>[Link]</version>
</dependency>
<!-- MySQL Connector-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
med@[Link]
Persistance de la classe
Compte
package [Link];
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
@XmlRootElement
@Entity
public class Compte implements
Serializable { @Id
@GeneratedValue(strategy=[Link]
Y) private Long code;
private double solde;
private Date
dateCreation;
// Getters et Setters
// Constructeurs
}
med@[Link]
src/main/resources/META-INF/[Link]
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
[Link] ">
<persistence-unit name="UP_EBOUTIQUE" transaction-type="RESOURCE_LOCAL">
<provider>[Link]</provider>
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="[Link]" value="update"/>
<property name="[Link]"
value="[Link]
t"/>
</properties>
</persistence-unit>
</persistence>
med@[Link]
Configuration JPA avec Spring
IOC
med@[Link]
Maven Properties

<properties>
<java-version>1.6</java-version>
<[Link]-
version>[Link]</[Link]-
version>
<[Link]-version>1.6.10</[Link]-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>

med@[Link]
Maven Dependencies
<!-- Spring -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-context</artifactId>
<version>${[Link]-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${[Link]-version}</version>
</dependency>
med@[Link]
Maven Dependencies
<!-- Spring -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-tx</artifactId>
<version>${[Link]-version}</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-orm</artifactId>
<version>${[Link]-version}</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-beans</artifactId>
<version>${[Link]-version}</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-core</artifactId>
<version>${[Link]-version}</version>
</dependency>

med@[Link]
Configuration JPA avec Spring
IOC :
/EBoutiqueV2/src/main/resources/
[Link]
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="[Link]
xmlns:xsi="[Link]
xmlns:context="[Link]
ext" xmlns:tx="[Link]
xsi:schemaLocation="[Link] [Link]
[Link] [Link]
[Link] [Link]

<bean id="datasource"
class="[Link]
e">
<property name="driverClassName" value="[Link]"></property>
<property name="url" value="jdbc:mysql://localhost:3306/eBanque"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
Configuration JPA avec Spring
IOC :
/EBoutiqueV2/src/main/resources/
[Link]
<bean id="persistenceUnitManager"
class="[Link]">
<property name="defaultDataSource" ref="datasource"></property>
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/[Link]</value>
</list>
</property>
</bean>
<bean id="entityManagerFactory"
class="[Link]">
<property name="persistenceUnitManager" ref="persistenceUnitManager"></property>
<property name="persistenceUnitName" value="UP_EBOUTIQUE"></property>
</bean>
<bean id="transactionManager"
class="[Link]">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:annotation-config></context:annotation-config>
</beans>
Tester la persistance des
entités
 Créer la base de données
eBanque
 Redéployer le projet
 La table compte devrait être
générée
med@[Link]
Couche DAO

med@[Link]
Interface IBanqueDAO
package [Link];
import [Link];
import [Link];
public interface IBanqueDAO {
public void addCompte(Compte c);
public List<Compte>
listComptes(); public Compte
getCompte(Long code);
public void verser(Long code,double mt);
public void retirer(Long code, double
mt);
public void virement(Long cpte1,Long cpte2,double
mt); public void deleteCompte(Long code);
}
med@[Link]
Implémentation DAO : ORM avec JPA
package [Link];
import [Link].*; import [Link].*;
import [Link];
public class BanqueDAOImpl implements IBanqueDAO
{ @PersistenceContext
private EntityManager em;
@Override
public void addCompte(Compte c) {
[Link](c); } @Override
public List<Compte> listComptes() {
Query req=[Link]("select c from Compte
c"); return [Link]();
}
@Override
public Compte getCompte(Long code) {
Compte cp=[Link]([Link],
code);
if(cp==null) throw new RuntimeException("Compte
Introuvable"); return cp;
}

med@[Link]
Implémentation DAO : ORM avec JPA
@Overrid
e
public void verser(Long code, double mt) {
Compte cp=getCompte(code); [Link]([Link]()+mt);
}
@Override
public void retirer(Long code, double mt) {
Compte cp=getCompte(code);
if(mt>[Link]()) throw new RuntimeException("Solde
Insuffisant"); [Link]([Link]()-mt);
}
@Override
public void virement(Long cpte1, Long cpte2, double mt) {
retirer(cpte1, mt); verser(cpte2, mt);
}
@Override
public void deleteCompte(Long code) {
Compte cp=getCompte(code);
[Link](cp);
}
}
med@[Link]
Couche Métier

med@[Link]
Interface
IBanqueMetier
package [Link];
import [Link];
import
[Link];
public interface IBanqueMetier {
public void addCompte(Compte c);
public List<Compte> listComptes();
public Compte getCompte(Long code);
public void verser(Long code,double mt);
public void retirer(Long code, double
mt);
public void virement(Long cpte1,Long cpte2,double
mt); public void deleteCompte(Long code);
}

med@[Link]
Implémentation Métier
package [Link];import [Link];
import [Link];
import [Link]; import
[Link]; @Transactional
public class BanqueMetierImpl implements
IBanqueMetier { private IBanqueDAO dao;
public void setDao(IBanqueDAO dao) { [Link] = dao; }
@Override
public void addCompte(Compte c) { [Link](c);}
@Override
public List<Compte> listComptes() { return
[Link](); } @Override
public Compte getCompte(Long code) { return [Link](code); }

med@[Link]
Implémentation Métier (suite)
@Overrid
e
public void verser(Long code, double mt) { [Link](code, mt); }
@Override
public void retirer(Long code, double mt) { [Link](code,
mt);
}
@Override
public void virement(Long cpte1, Long cpte2, double
mt) { [Link](cpte1, cpte2, mt);
}
@Override
public void deleteCompte(Long code) {
[Link](code);
}
}
med@[Link]
Web Service
package [Link]; import [Link].*; import
[Link].*; import [Link];
import [Link];
@WebService
public class BanqueService {
private IBanqueMetier
metier;
@WebMethod(exclude=true)
public void setMetier(IBanqueMetier metier) {[Link] = metier;
} @WebMethod
@Oneway
public void addCompte(@WebParam(name="solde")double solde){
[Link](new Compte(null, solde,new Date()));
}
@WebMethod
public Compte getCompte(@WebParam(name="code")Long
code){ return [Link](code);
}
@WebMethod
public List<Compte> getComptes(){ return [Link](); }
Web Service
@WebMethod
public void verser(
@WebParam(name="code")Long code,
@WebParam(name="montant")double mt){ [Link](code,
mt); } @WebMethod
public void retirer(
@WebParam(name="code")Long code,
@WebParam(name="montant")double mt){ [Link](code, mt); }
@WebMethod
public void virement(
@WebParam(name="cpte1")Long cpte1,
@WebParam(name="cpte2")Long cpte2,
@WebParam(name="montant")double mt){ [Link](cpte1,
cpte2, mt); }
@WebMethod
public void supprimerCompte(@WebParam(name="code")Long code){
[Link](code);
} }
Injection des
dépendances

med@[Link]
Injection des dépendance :root-
[Link]

<!-- Root Context: defines shared resources visible to all other web
components -->
<bean id="dao" class="[Link]"></bean>
<bean id="metier" class="[Link]">
<property name="dao" ref="dao"></property>
</bean>
<bean id="service" class="[Link]">
<property name="metier" ref="metier"></property>
</bean>
<bean
class="[Link]">
<property name="baseAddress"
value="[Link]
</bean>
med@[Link]
Injection des dépendance :root-
[Link]
<bean id="datasource" class="[Link]">
<property name="driverClassName" value="[Link]"></property>
<property name="url" value="jdbc:mysql://localhost:3306/eBanque"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<bean id="persistenceUnitManager"
class="[Link]
ager">
<property name="defaultDataSource" ref="datasource"></property>
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/[Link]</value>
</list>
</property>
</bean>
<bean id="entityManagerFactory"
class="[Link]">
<property name="persistenceUnitManager" ref="persistenceUnitManager"></property>
<property name="persistenceUnitName" value="UP_BANQUE"></property>
</bean>
<bean id="transactionManager" class="[Link]">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:annotation-config></context:annotation-config>
med@[Link]
Tester les méthodes avec un
analyseur SOAP :SoapUI
SGBD

Couche DAO

Couche Métier

Web Service

SOAP

SoapUI
med@[Link]
Tester les méthodes
Requête SOAP pour ajouter un compte
<soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ser="[Link]
<soapenv:Header/>
<soapenv:Body>
<ser:addCompte>
<solde>20000</solde>
</ser:addCompte>
</soapenv:Body>
</soapenv:Envelope>
Pas de réponse SOAP (@oneway )

med@[Link]
Tester les méthodes
Requête SOAP pour consulter un compte
<soapenv:Envelope
xmlns:soapenv="[Link]
" xmlns:ser="[Link]
<soapenv:Header/>
<soapenv:Body>
<ser:getCompte>
<code>1</code>
</ser:getCompte>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP

<S:Envelope xmlns:S="[Link]
<S:Body>
<ns2:getCompteResponse
xmlns:ns2="[Link]
<return>
<code>1</code>
<dateCreation>2014-01-24T[Link]Z</dateCreation>
<solde>92600.0</solde>
</return>
</ns2:getCompteResponse>
</S:Body>
</S:Envelope>
med@[Link]
Tester les méthodes
Requête SOAP pour consulter les comptes
<soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ser="[Link]
<soapenv:Header/>
<soapenv:Body>
<ser:getComptes/>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP
<S:Envelope xmlns:S="[Link]
<S:Body>
<ns2:getComptesResponse xmlns:ns2="[Link]
<return>
<code>1</code>
<dateCreation>2014-01-24T[Link]Z</dateCreation>
<solde>92600.0</solde>
</return>
<return>
<code>2</code>
<dateCreation>2014-01-25T[Link]Z</dateCreation>
<solde>20000.0</solde>
</return>
</ns2:getComptesResponse>
</S:Body>
</S:Envelope>

med@[Link]
Tester les méthodes
Requête SOAP pour verser un montant
<soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ser="[Link]
<soapenv:Header/>
<soapenv:Body>
<ser:verser>
<code>1</code>
<montant>2000</montant>
</ser:verser>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP
<S:Envelope
xmlns:S="[Link]
<S:Body>
<ns2:verserResponse
xmlns:ns2="[Link]
</S:Body>
</S:Envelope>
med@[Link]
Retirer un montant
Requête SOAP pour verser un montant
<soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ser="[Link]
<soapenv:Header/>
<soapenv:Body>
<ser:retirer>
<code>1</code>
<montant>7000000</montant>
</ser:retirer>
</soapenv:Baody>
</soapenv:Envelope>

Réponse SOAP
<S:Envelope xmlns:S="[Link]
<S:Body>
<S:Fault xmlns:ns4="[Link]
envelope">
<faultcode>S:Server</faultcode>
<faultstring>Solde Insuffisant</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
med@[Link]
Effectuter un virement
Requête SOAP pour effectuer un virement
<soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ser="[Link]
<soapenv:Header/>
<soapenv:Body>
<ser:virement>
<cpte1>1</cpte1>
<cpte2>2</cpte2>
<montant>8000</montant>
</ser:virement>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP
<S:Envelope
xmlns:S="[Link]
<S:Body>
<ns2:virementResponse
xmlns:ns2="[Link]
</S:Body>
</S:Envelope>
med@[Link]
Supprimer un compte
Requête SOAP pour supprimer un compte
<soapenv:Envelope
xmlns:soapenv="[Link]
xmlns:ser="[Link]
<soapenv:Header/>
<soapenv:Body>
<ser:supprimerCompte>
<code>2</code>
</ser:supprimerCompte>
</soapenv:Body>
</soapenv:Envelope>

Réponse SOAP
<S:Envelope xmlns:S="[Link]
<S:Body>
<ns2:supprimerCompteResponse
xmlns:ns2="[Link]
</S:Body>
</S:Envelope>
med@[Link]
Web services dans une
application web J2EE basée sur
EJB3 et JBoss7.1
 Dans une application web J2EE basée sur
un serveur d’application J2EE
◦ Web Sphere
◦ Jboss
◦ Jonas
◦ Glassfish
 Aucune configuration n’est nécessaire pour
déployer le web service
 Il suffit de créer un projet web basé sur le
serveur d’application
 Créer le web service
 Démarrer le serveur et déployer le projet web
 Chaque serveur d’application possède
sa propre implémentation JAX WS :
CXF, AXIS, etc…
med@[Link]
Application
 Créer une application qui permet de gérer des
comptes via un service web.
 Chaque compte est défini par un code, un solde, la date
de création
 Les comptes sont stockés dans une base de données
MYSQL.
 Le mapping objet relationnel est effectué via JPA
(EJB Entity et Session )
 La couche service est représenté par un web
service de type JAXRS.
 L’application doit permettre de :
◦ Ajouter un compte
◦ Consulter tous les compte
◦ Consulter un compte sachant son code
◦ Effectuer un versement d’un montant dans un compte
◦ Effectuer un retrait d’un montant sur un compte
 L’application web sera déployé dans un serveur JBoss7
 Créer un client java et un client PHP.
med@[Link]
Architecture
Seveur d’application J2EE : JBOSS (http :8080)

Couche Couche Data


Métier JPA Sources
EJB
EntityManager
Entity MYSQ
EJB
L
Session Hibernat
e JDBC
Couche
Service Web JNDI
Service JaxWS

SOAP
SOAP Apache :8888

Oxygen HTTP
med@[Link]
Structure du projet J2EE

Configuration de l’unité de
Persistance JPA
EJB Session

EJB Entity
Interface Local de

l’EJB Web Service

med@[Link]
Données manipulées : Entity Compte
package metier;
import [Link]; import [Link]; import
[Link].*; @Entity
@Table(name="COMPTES")
public class Compte implements Serializable
{ @Id
@GeneratedValue(strategy=[Link]
TITY)
private Long code;
private double
solde;
private Date dateCreation;
public Compte() {
}
public Compte(double solde) {
[Link] = solde;
[Link]=new
Date();
}
// Getters et Setters
}
med@[Link]
Interface Locale

package metier;
import
[Link];
import [Link];
@Local
public interface IBanqueLocal {
public Compte addCompte(Compte
c); public List<Compte>
getAllComptes();
public void verser(Long code,double montant);
public void retirer(Long code,double montant);
public Compte consulterCompte(Long code);
}
med@[Link]
Implémentation EJB Session sans état
package metier;
import
[Link];
import
[Link];
import
[Link].*;
@Stateless(name="BP")
public class BanqueEJBImpl implements IBanqueLocal {
@PersistenceContext(unitName="UP_BP")
EntityManager em;
@Override
public Compte addCompte(Compte c) {
[Link](c);
return c;
}
@Override
public List<Compte> getAllComptes() {
Query req=[Link]("select c from Compte c");
return [Link]();
}
med@[Link]
Implémentation EJB Session sans état
@Override
public void verser(Long code, double
montant) { if(montant<=0) throw new
RuntimeException ("Le Montant doit être
supérieur à zero"); Compte
c=[Link]([Link], code);
[Link]([Link]()+montant);
[Link](c);
}
@Override
public void retirer(Long code, double montant) {
if(montant<=0) throw new RuntimeException
("Le Montant doit être supérieur à zero");
Compte c=[Link]([Link], code);
if([Link]()<=montant) throw new RuntimeException
("Solde Insuffisant");
[Link]([Link]()-montant);
}
med@[Link]
Implémentation EJB Session sans état
@Override
public Compte consulterCompte(Long code) {
Compte c=[Link]([Link], code);
if(c==null) throw new RuntimeException
("Compte introuvable");
return c;
}
}

med@[Link]
Configuration de l’unité
de persistance :
[Link]
<?xml version="1.0" encoding="UTF-8"?>
<persistence
xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
ence
[Link]
.xsd" version="1.0">
<persistence-unit name="UP_BP">
<jta-data-source>java:/dsBP</jta-data-source>
<properties>
<property name="[Link]" value="update"/>
</properties>
</persistence-unit>
</persistence>
med@[Link]
Data source
 Fichier [Link] de JBoss
<datasources>
<datasource jndi-name="java:/dsBP" pool-name="dsBP"
enabled="true" >
<connection-url>jdbc:mysql://[Link]:3306/DB_BP</connection-
url>
<driver-class>[Link]</driver-class>
<driver>mysql</driver>
<security>
<user-name>root</user-name>
<password></password>
</security>
</datasource>
<drivers>
<driver name="mysql" module="[Link]"/>
</drivers>
</datasources>
med@[Link]
Web Service
package service;
import
[Link];
import [Link];import [Link].*;
import [Link];import [Link];
@WebService
public class BanqueService {
@EJB
private IBanqueLocal metier;
@WebMethod
public Compte addCompte(@WebParam(name="solde")double
solde) { return [Link](new Compte(solde));
}
@WebMethod
public List<Compte> getAllComptes()
{ return [Link]();
}

med@[Link]
Web Service
@WebMethod
public void verser(@WebParam(name="code")Long code,
@WebParam(name="montant")double montant) {
[Link](code, montant);
}
@WebMethod
public void retirer(@WebParam(name="code")Long
code, @WebParam(name="montant")double montant) {
[Link](code, montant);

}
@WebMethod
public Compte consulterCompte(@WebParam(name="code")Long
code) { return [Link](code);
}
}

med@[Link]
Déployer et Tester le projet
Web
 Démarrer le serveur JBoss
 Déployer le projet Web
 Consulter le WSDL
 Tester Le web service avec Oxygen
med@[Link]
Analyse du WSDL

med@[Link]
Resumé du WSDL

med@[Link]
Le schéma XML des données
échangées :
<wsdl:types>
<xs:schema elementFormDefault="unqualified" targetNamespace="[Link]
version="1.0" xmlns:tns="[Link]
xmlns:xs="[Link]
<xs:element name="addCompte" type="tns:addCompte"/>
<xs:element name="addCompteResponse" type="tns:addCompteResponse"/>
<xs:element name="consulterCompte" type="tns:consulterCompte"/>
<xs:element name="consulterCompteResponse"
type="tns:consulterCompteResponse"/>
<xs:element name="getAllComptes" type="tns:getAllComptes"/>
<xs:element name="getAllComptesResponse"
type="tns:getAllComptesResponse"/>
<xs:element name="retirer" type="tns:retirer"/>
<xs:element name="retirerResponse" type="tns:retirerResponse"/>
<xs:element name="verser" type="tns:verser"/>
<xs:element name="verserResponse" type="tns:verserResponse"/>
<xs:complexType name="getAllComptes">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="getAllComptesResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return"
type="tns:compte"/>
</xs:sequence>
</xs:complexType>

med@[Link]
Le schéma XML des données
échangées :
<xs:complexType name="compte">
<xs:sequence>
<xs:element minOccurs="0" name="code" type="xs:long"/>
<xs:element minOccurs="0" name="dateCreation" type="xs:dateTime"/>
<xs:element name="solde" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="consulterCompte">
<xs:sequence>
<xs:element minOccurs="0" name="code" type="xs:long"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="consulterCompteResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:compte"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addCompte">
<xs:sequence>
<xs:element name="solde" type="xs:double"/>
</xs:sequence>
</xs:complexType>
med@[Link]
Le schéma XML des données
échangées :
<xs:complexType name="addCompteResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:compte"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="retirer">
<xs:sequence>
<xs:element minOccurs="0" name="code" type="xs:long"/>
<xs:element name="montant" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="retirerResponse">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="verser">
<xs:sequence>
<xs:element minOccurs="0" name="code" type="xs:long"/>
<xs:element name="montant" type="xs:double"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="verserResponse">
<xs:sequence/>
</xs:complexType>
</xs:schema>
</wsdl:types> med@[Link]
Description des messages
 <wsdl:message name="retirer">
<wsdl:part element="tns:retirer" name="parameters">
</wsdl:part>
</wsdl:message>
 <wsdl:message name="retirerResponse">
<wsdl:part element="tns:retirerResponse"
name="parameters">
</wsdl:part>
</wsdl:message>
med@[Link]
L’élément PortType
 <wsdl:portType name="BanqueService">

<wsdl:operation name="getAllComptes">
<wsdl:input message="tns:getAllComptes"
name="getAllComptes"></wsdl:input>
<wsdl:output message="tns:getAllComptesResponse"
name="getAllComptesResponse">
</wsdl:output>
</wsdl:operation>

<wsdl:operation name="consulterCompte">
<wsdl:input message="tns:consulterCompte" name="consulterCompte">
</wsdl:input>
<wsdl:output message="tns:consulterCompteResponse"
name="consulterCompteResponse">
</wsdl:output>
</wsdl:operation>
………
 </wsdl:portType>
med@[Link]
L’élément SoapBinding
 <wsdl:binding name="BanqueServiceServiceSoapBinding"
type="tns:BanqueService">
<soap:binding style="document"
transport="[Link]
<wsdl:operation name="getAllComptes">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getAllComptes">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getAllComptesResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="consulterCompte">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="consulterCompte">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="consulterCompteResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
…….
</wsdl:binding> med@[Link]
L’élément Service
<wsdl:service name="BanqueServiceService">
<wsdl:port
binding="tns:BanqueServiceServiceSoapBind
ing" name="BanqueServicePort">
<soap:address
location="[Link]
e/Banque
Service"/>
</wsdl:port>
</wsdl:service>
med@[Link]
Oxygen

 <SOAP-ENV:Envelope xmlns:SOAP-
ENV="[Link]
nvelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<addCompte xmlns="[Link]
<solde xmlns="">3000</solde>
</addCompte>
</SOAP-ENV:Body>
</SOAP- Requête SOAP pour ajouter un compte
ENV:Envelope>

 <soap:Envelope xmlns:soap="[Link]
<soap:Body>
<ns2:addCompteResponse xmlns:ns2="[Link]
<return>
<code>11</code>
<dateCreation>2013-06-05T[Link].469+01:00</dateCreation>
<solde>3000.0</solde>
</return>
</ns2:addCompteResponse>
</soap:Body>
</ Réponse SOAP après ajout d’un
soap:Envelop
e> compte
med@[Link]
Oxygen : Effectuer un
versement
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="[Link]
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<verser xmlns="[Link]
<code xmlns="">1</code>
<montant xmlns="">9000</montant>
</verser>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> Requête SOAP pour verser un montant

<soap:Envelope
xmlns:soap="[Link]
e/">
<soap:Body>
<ns2:verserResponse xmlns:ns2="[Link]
</soap:Body>
</soap:Envelope> Réponse SOAP
med@[Link]
Oxygen : Effectuer le
retrait
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="[Link]
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<retirer xmlns="[Link]
<code xmlns="">1</code>
<montant xmlns="">600000</montant>
</retirer>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Requête SOAP pour retirer un montant>solde

<soap:Envelope
xmlns:soap="[Link]
e/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>[Link]
: Solde Insuffisant</faultstring>
</soap:Fault>
</ </soap:Envelope>
soap:Body>
Réponse SOAP
qui retourne
une exception

m
e
d
@
y
o
u
s
s
f
i
.
n
e
t
Oxygen : Consulter les Comptes
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="[Link]
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<getAllComptes xmlns="[Link]
</SOAP-ENV:Body>
</SOAP- Requête SOAP pour consulter tous les
ENV:Envelope>
comptes

<soap:Envelope
xmlns:soap="[Link]
<soap:Body>
<ns2:getAllComptesResponse xmlns:ns2="[Link]
<return>
<code>1</code>
<dateCreation>2013-06-04T[Link]+01:00</dateCreation>
<solde>29000.0</solde>
</return>
<return>
<code>3</code>
<dateCreation>2013-06-04T[Link]+01:00</dateCreation>
<solde>15000.0</solde>
</return>
</ns2:getAllComptesResponse>
</ Réponse SOAP qui retourne une
soap:Body> exception
</
med@youssfi.
soap:Envelop net
e>
Client SOAP PHP

med@[Link]
Client PHP
<?php
try {
$clientSoap=new
SoapClient("[Link]
wsdl");
if(isset($_GET['action'])){
$operation=$_GET['action'];
if(($operation=="verser")||($operation=="retirer")){
$param1=new stdClass();
$param1->code=$_GET['code'];
$param1->montant=$_GET['montant'];
$clientSoap-> soapCall($operation, array($param1));
$param2=new stdClass();
$param2->code=$_GET['code'];
$repSoap=$clientSoap-> soapCall("consulterCompte", array($param2));
}

med@[Link]
Client PHP
else if($operation=="addCompte"){
$param1=new stdClass();
$param1->solde=$_GET['solde'];
$repSoap=$clientSoap-> soapCall($operation, array($param1));
}
else if($operation=="consulterCompte"){
$param1=new stdClass();
$param1->code=$_GET['code'];
$repSoap=$clientSoap-> soapCall($operation, array($param1));
}
}
else{
$repSoap=$clientSoap-> soapCall("getAllComptes", array());
}
} catch (Exception $e) {
}
?>
med@[Link]
Client PHP
<html>
<head>
</head>
<body>
<div>
<form action="[Link]" method="get">
Solde :<input type="text" name="solde">
<input type="submit" name="action" value="addCompte">
</form>
</div>
<div>
<form action="[Link]" method="get">
Code :<input type="text" name="code">
Montant :<input type="text" name="montant">
<input type="submit" name="action" value="consulterCompte">
<input type="submit" name="action" value="verser">
<input type="submit" name="action" value="retirer">
</form>
</div>
<a href="[Link]">Afficher tous les comptes</a>
med@[Link]
Client PHP
<table border="1" width="80%">
<tr>
<th>Code</th><th>Solde</th><th>Date Création</th>
</tr>
<?php
if(isset($repSoap)){
if(is_array($repSoap->return)){
$tab=$repSoap->return;
} else{
$tab=array($repSoap->return);
}
foreach ($tab as $cpte){?>
<tr>
<td><?php echo($cpte->code)?></td><td><?php echo($cpte->solde)?></td>
<td><?php echo($cpte->dateCreation)?></td>
</tr>
<?php } } ?>
</table>
<?php if(isset($e)){?> <li><?php echo ($e->getMessage())?></li> <?php }?>
</body></html>
med@[Link]
Client PHP
<table border="1" width="80%">
<tr>
<th>Code</th><th>Solde</th><th>Date Création</th>
</tr>
<?php
if(isset($repSoap)){
if(is_array($repSoap->return)){
$tab=$repSoap->return;
} else{
$tab=array($repSoap->return);
}
foreach ($tab as $cpte){?>
<tr>
<td><?php echo($cpte->code)?></td><td><?php echo($cpte->solde)?></td>
<td><?php echo($cpte->dateCreation)?></td>
</tr>
<?php } } ?>
</table>
<?php if(isset($e)){?> <li><?php echo ($e->getMessage())?></li> <?php }?>
</body></html>
med@[Link]
UDDI

med@[Link]
UDDI
 L'annuaire des services UDDI est un
standard pour la publication et la
découverte des informations sur les
services Web.
 La spécification UDDI est une
initiative lancée par ARIBA,
Microsoft et IBM.
 Cette spécification n'est pas
gérée par le W3C mais par le
groupe OASIS.
 La spécification UDDI vise à créer
une plate- forme indépendante, un
espace de travail (framework)
ouvert pour la description, la
découverte et l'intégration des
services des entreprises.
med@[Link]
Consultation de l'annuaire
 L'annuaire UDDI se concentre sur le
processus de découverte de l'architecture
orientée services (SOA), et utilise des
technologies standards telles que XML,
SOAP et WSDL qui permettent de simplifier
la collaboration entre partenaires dans le
cadre des échanges commerciaux.
 L'accès au référentiel s'effectue de
différentes manières.
◦ Les pages blanches comprennent la liste des
entreprises ainsi que des informations
associées à ces dernières (coordonnées,
description de l'entreprise, identifiants...).
◦ Les pages jaunes recensent les services Web
de chacune des entreprises sous le standard
WSDL.
◦ Les pages vertes fournissent des informations
techniques précises sur les services fournis.
med@[Link]
Architecture
 Les entreprises publient les descriptions de leurs services Web
en UDDI, sous la forme de fichiers WSDL.
 Ainsi, les clients peuvent plus facilement rechercher les
services Web dont ils ont besoin en interrogeant le registre
UDDI.
 Lorsqu'un client trouve une description de service Web qui lui
convient, il télécharge son fichier WSDL depuis le registre
UDDI. Ensuite, à partir des informations inscrites dans le fichier
WSDL, notamment la référence vers le service Web, le client
peut invoquer le service Web et lui demande d'exécuter
certaines de ses fonctionnalités.
 Le scénario classique d'utilisation de UDDI est illustré ci-
dessous. L'entreprise B a publié le service Web S, et
l'entreprise A est client de ce service :

Entreprse UDDI Entreprse B


A

Publication du Web
Service Découverte du Web Service
SOAP
SOAP

med@[Link]
Structures de données UDDI
 Unregistre UDDI se compose de quatre
types de structures de données,
◦ le businessEntity,
◦ Le businessService,
◦ le bindingTemplate
◦ et la tModel.

med@[Link]
BusinessEntity
(entité d'affaires)
 Les « businessEntities » sont
en quelque sorte les pages
blanches d'un annuaire UDDI.
 Elles décrivent les organisations
ayant publié des services dans le
répertoire.
 On y trouve notamment
◦ le nom de l'organisation,
◦ ses adresses (physiques et Web),
◦ des éléments de classification,
◦ une liste de contacts
◦ ainsi que d'autres informations.
med@[Link]
BusinessService
(service d'affaires)
 Les « businessServices » sont en
quelque sorte les pages jaunes
d'un annuaire UDDI.
 Elles décrivent de manière non
technique les services proposés par
les différentes organisations.
 On y trouve essentiellement
◦ le nom et la description textuelle des
services
◦ ainsi qu'une référence à l'organisation
proposant le service
◦ et un ou plusieurs « bindingTemplate ».
med@[Link]
BindingTemplate (modèle
de rattachement)
 UDDI permet de décrire des
services Web utilisant HTTP, mais
également des services invoqués
par d'autres moyens (SMTP, FTP...).
 Les « bindingTemplates »
donnent les coordonnées des
services.
 Ce sont les pages vertes de
l'annuaire UDDI.
 Ils contiennent notamment une
description, la définition du point
d'accès (une URL) et les éventuels
« tModels » associés.

med@[Link]
tModel (index)
 Les « tModels » sont les
descriptions techniques des
services.
 UDDI n'impose aucun format
pour ces descriptions qui peuvent
être publiées sous n'importe quelle
forme et notamment sous forme de
documents textuels (XHTML, par
exemple).
 C'est à ce niveau que WSDL
intervient comme le vocabulaire de
choix pour publier des descriptions
techniques de services.
med@[Link]
L'interface UDDI
 L'interface UDDI est définie sous forme de
documents UDDI et implémentée sous forme
de service Web SOAP.
 Elle est composée des modules suivants :
◦ Interrogation inquiry : Cette interface permet de
rechercher des informations dans un répertoire
UDDI.
◦ Publication : Cette interface permet de
publier des informations dans un
répertoire UDDI.
◦ Sécurité : cette interface est utilisée pour obtenir
et révoquer les jetons d'authentification
nécessaires pour accéder aux enregistrements
protégés dans un annuaire UDDI.
◦ Contrôle d'accès et propriété custody and
ownership transfer: Cette interface permet de
transférer la propriété d'informations (qui est à
l'origine attribuée à l'utilisateur ayant publié ces
informations) et de gérer les droits d'accès
associés.
◦ Abonnement Subscription : Cette interface
permet à un client de s'abonner à un ensemble
d'informations et d'être averti lors des modifications
de ces informations.

med@[Link]
WEB SERVICES REST
FULL

med@[Link]
RESTful
 REST (REpresentational State
Transfer) ou RESTful est un style
d’architecture pour les systèmes
hypermédia distribués,
 Créé par Roy Fielding en 2000 dans le
chapitre 5 de sa thèse de doctorat.
 REST est un style d’architecture permettant
de construire des applications (Web,
Intranet,Web Service).
 Il s’agit d’un ensemble de conventions et
de bonnes pratiques à respecter et non
d’une technologie à part entière.
 L’architecture REST utilise les spécifications
originelles du protocole HTTP, plutôt que
de réinventer une surcouche (comme le
font SOAP ou XML-RPC par exemple).
med@[Link]
REST: Principe
Description du Service Web
permettant de générer la partie
cliente

C WADL HTTP XML, JSON HTTP


Clien l
t i
Lege e HTTP HTTP
r n
t
Clien
t M
Java o
b
Clien i
t l
.net e
a
W i Web Service
e n
b e Methode
r
1()
C
Methode
o
2()
n
t
med@[Link]
Règles de RESTful
 Règle n°1 :
◦ l’URI comme identifiant des ressources
 Règle n°2 :
◦ les verbes HTTP comme identifiant des
opérations
 Règle n°3 :
◦ les réponses HTTP comme
représentation des ressources
 Règle n°4 :
◦ les liens comme relation entre ressources
 Règle n°5 :
◦ un paramètre comme jeton d’authentification

med@[Link]
Règle N°1 :
l’URI comme identifiant des
ressources

REST se base sur les URI


(Uniform Resource
Identifier) afin d’identifier
une ressource.
Ainsi une application se doit de
construire ses URI (et donc ses
URL) de manière précise, en
tenant compte des contraintes
REST.
Il est nécessaire de prendre en
compte la hiérarchie des
ressources et la sémantique des
URL pour les éditer :
med@[Link]
Règle N°1 :
Quelques exemples de construction d’URL avec
RESTful :

 Liste des livres


◦ NOK : [Link]
◦ OK : [Link]
 Filtre et tri sur les livres
◦ NOK : [Link]
◦ OK : [Link]
 Affichage d’un livre
◦ NOK : [Link]
◦ OK : [Link]
 Tous les commentaires sur un livre
◦ NOK : [Link]
◦ OK : [Link]

med@[Link]
Règle N°1 :
Quelques exemples de construction d’URL avec
RESTful :

 Affichage d’un commentaire sur un livre


◦ NOK : [Link]
◦ OK : [Link]
 En construisant correctement les URI, il est
possible de les trier, de les hiérarchiser et
donc d’améliorer la compréhension du
système.
 L’URL suivante peut alors être
décomposée logiquement :
◦ [Link] => un
commentaire pour un livre
◦ [Link]
=> tous les commentaires pour un livre
◦ [Link] => un livre
◦ [Link] => tous les livres
med@[Link]
Règle n°2 : les verbes HTTP comme
identifiant des opérations
 La seconde règle d’une architecture REST est
d’utiliser les verbes HTTP existants plutôt que
d’inclure l’opération dans l’URI de la ressource.
 Ainsi, généralement pour une ressource, il y a 4
opérations possibles (CRUD) :
◦ Créer (create)
◦ Afficher (read)
◦ Mettre à jour (update)
◦ Supprimer (delete)
 HTTP propose les verbes correspondant :
◦ Créer (create) => POST
◦ Afficher (read) => GET
◦ Mettre à jour (update) => PUT
◦ Supprimer (delete) => DELETE

med@[Link]
Règle n°2 : les verbes HTTP comme
identifiant des opérations
 Exemple d’URL pour une ressource donnée
(un livre par exemple) :
 Créer un livre
 NOK : GET [Link]
 OK : POST [Link]

 Afficher
◦ NOK : GET [Link]
◦ OK : GET [Link]
 Mettre à jour
◦ NOK : POST [Link]
◦ OK : PUT [Link]
 Supprimer
◦ NOK : GET [Link]
◦ OK : DELETE [Link]
med@[Link]
Règle n°3 : les réponses HTTP
comme représentation des
ressources
 Il est important d’avoir à l’esprit que la
réponse envoyée n’est pas une ressource,
c’est la représentation d’une ressource.
 Ainsi, une ressource peut avoir plusieurs
représentations dans des formats divers :
HTML, XML, CSV, JSON, etc.
 C’est au client de définir quel format de réponse
il souhaite reçevoir via l’entête Accept.
 Il est possible de définir plusieurs formats.
◦ Réponse en HTML
 GET /books
Host:
[Link]
Accept: text/html
◦ Réponse en XML
 GET /books
Host: [Link]
Accept:
application/xml
med@[Link]
Règle n°4 : les liens comme
relation entre ressources
 Les liens d’une ressource vers une autre ont tous une chose
en commun
: ils indiquent la présence d’une relation.
 Il est cependant possible de la décrire afin d’améliorer la
compréhension du système.
 Pour expliciter cette description et indiquer la nature
de la relation, l’attribut rel doit être spécifier sur tous
les liens.
 Ainsi l’IANA donne une liste de relation parmi lesquelles :
◦ contents
◦ edit
◦ next
◦ last
◦ payment
◦ etc.
 La liste complète sur le site de l’IANA :
◦ [Link]
[Link]

med@[Link]
Règle n°4 : les liens comme
relation entre ressources
 Exemple de réponse en XML d’une liste
paginée de livres :
<?xml>
<search>
<link rel="self" title="self" href="[Link] />
<link rel="next" title="next" href="[Link] />
<link rel="last" title="last" href="[Link] />
<book>
//...
</book>
</search>

med@[Link]
Règle n°5 : un paramètre comme
jeton d’authentification
 C’est un des sujets les plus souvent abordé
quand on parle de REST : comment authentifier
une requête ?
 La réponse est très simple et est massivement
utilisée par des APIs renommées
(Google,Yahoo, etc.) : le jeton
d’authentification.
 Chaque requête est envoyée avec un jeton
(token) passé en paramètre $_GET de la
requête.
 Ce jeton temporaire est obtenu en envoyant
une première requête d’authentification puis en
le combinant avec nos requêtes.
 Ainsi, on peut construire le scénario suivant :
med@[Link]
Règle n°5 : un paramètre comme
jeton d’authentification
 1. demande d’authentification
◦ GET /users/123/authenticate?
pass=lkdnssdf54d47894f5123002fds2sd360s0
<?xml>
<user>
<id>123</id>
<name>Nicolas Hachet</name>
</user>
<token>
fsd531gfd5g5df31fdg3g3df45
</token>

2. accès aux ressources :


Cet token est ensuite utilisé pour générer un hash de la requête de
cette façon :
hash = SHA1(token + requete)
hash = SHA1(fsd531gfd5g5df31fdg3g3df45 + "GET
/books") hash = 456894ds4q15sdq156sd1qsd1qsd156156

 C’est ce hash qui est passé comme jeton afin de valider


l’authentification pour cette requête:
GET /books?user=123&hash=456894ds4q15sdq156sd1qsd1qsd156156
med@[Link]
JAX-RS : la spécification
 JAX-RS est l’acronyme Java API for RESTful Web
Services
 Décrite par la JSR 311 ([Link]/en/jsr/summary?
id=311)
 Version courante de la spécification est la 1.1
 Depuis la version 1.1, JAX-RS fait partie
intégrante de la spécification Java EE 6 au
niveau de la pile Service Web
 Cette spécification décrit uniquement la mise
en œuvre de services Web REST coté serveur
 Le développements des Services Web REST repose
sur
 l’utilisation de classes Java et d’annotations
med@[Link]
JAX-RS : la spécification
 Différentes implémentations de la
spécification JAX-RS sont disponibles
◦ JERSEY : implémentation de référence
fournie par Oracle Site projet :
[Link]
◦ CXF : fournie par Apache, la fusion entre
XFire et Celtix Site projet :
[Link]
◦ RESTEasy : fournie par JBoss Site
projet : [Link]/resteasy
◦ RESTlet : un des premiers framework
implémentant REST pour Java : Site projet :
[Link]
med@[Link]
JAX RS: fonctionnement
Description du Service Web
permettant de générer la partie
cliente

C WADL HTTP XML, JSON HTTP


Clien l
t i
Lege e HTTP HTTP
r n
t
Clien
t M
Java o
b
Clien i
t l
.net e
a
W i Web Service
e n
b e Methode
r
1()
C
Methode
o
2()
n
t
med@[Link]
JSON
 JSON (JavaScript Object Notation –
Notation Objet issue de JavaScript)
est un format léger d'échange de
données.
 Il est facile à lire ou à écrire pour des
humains. Il est aisément analysable ou
générable par des machines.
 JSON est un format texte complètement
indépendant de tout langage, mais les
conventions qu'il utilise seront familières
à tout programmeur habitué aux
langages descendant du C, comme par
exemple : C lui-même, C++, C#, Java,
JavaScript, Perl, Python et bien d'autres.
 Ces propriétés font de JSON un langage
d'échange de données idéal.
med@[Link]
Exemple XML/JSON
XML
<?xml version="1.0" encoding="UTF-8"?>
<comptes>
<compte type="courant">
<code>1</code>
<solde>4300</solde>
<dateCreation>2012-11-11</dateCreation>
</compte>
<compte type="epargne">
<code>2</code>
<solde>96000</solde>
<dateCreation>2012-12-11</dateCreation>
</compte>
</comptes>

JSON
[
{type:"courant" , code:1, solde:4300.50,dateCreation:"2012-11-11"},
{type:"epargne" , code:1, solde:4300.00,dateCreation:"2012-11-11"}
]
med@youssfi.
Structures de JSON
 JSON se base sur deux structures :
◦Une collection de couples nom/valeur.
◦Divers langages la réifient par un
objet, un enregistrement, une
structure, un dictionnaire, une table
de hachage, une liste typée ou un
tableau associatif.
 Ces structures de données sont
universelles. Pratiquement tous
les langages de programmation
modernes les proposent sous une
forme ou une autre.
med@[Link]
Les structures de données
JSON
 EnJSON, les structures de données prennent
les formes suivantes :
◦ Un objet, qui est un ensemble de couples
nom/valeur non ordonnés. Un objet commence par {
(accolade gauche) et se termine par } (accolade
droite). Chaque nom est suivi de : (deux- points) et
les couples nom/valeur sont séparés par , (virgule).
◦ Un tableau est une collection de valeurs
ordonnées. Un tableau commence par [ (crochet
gauche) et se termine par ] (crochet droit). Les
valeurs sont séparées par , (virgule).
◦ Une valeur peut être soit une chaîne de
caractères entre guillemets, soit un nombre,
soit true ou false ou null, soit
un objet soit un tableau. Ces structures peuvent être
imbriquées.
◦ Une chaîne de caractères est une suite de zéro
ou plus caractères Unicode, entre guillemets, et
utilisant les échappements avec antislash. Un
caratère est représenté par une chaîne d'un seul
caractère.

med@[Link]
Structure des données JSON

med@[Link]
Structure des données JSON

med@[Link]
Généralités sur JAX RS
 Le développement de Services Web
avec JAX-RS est basé sur des POJO
(Plain Old Java Object) en utilisant des
annotations spécifiques à JAX-RS
 Pas description requise dans des
fichiers de configuration
 Seule la configuration de la Servlet «
JAX-RS » est requise pour réaliser le pont
entre les requetés HTTP et les classes
Java annotées
 Un Service Web REST est déployé
dans une application Web
med@[Link]
Généralités sur JAX RS
 Contrairement aux Services Web
entendus il n’y a pas de possibilité de
développer un service REST à partir du
fichier de description WADL
 Seule l’approche Botton / Up est
disponible
◦ Créer et annoter un POJO
◦ Compiler, Déployer et Tester
◦ Possibilité d’accéder au document WADL
Le fichier de description WADL est
génèré automatiquement par JAX-
RS (exemple :
[Link]
l)
med@[Link]
Exemple de web service
RESTful

 Consulter un compte
 Consulter la liste des comptes
 Effectuer un versement
 Effectuer un retrait
 Effectuer un virement
 Supprimer un compte
med@[Link]
Exemple de web service
JAX RS
package [Link];
import [Link].*; import [Link].*;
import [Link];
import
[Link];
import [Link];
import [Link];
import
[Link];
@Component
@Path("/banque
")
public class BanqueRestService {
@Autowired
IBanqueMetier metier;

@POST
@Path("/comptes")
public void addCompte(@FormParam(value="solde")double solde){
[Link](new Compte(null, solde,new Date()));
}

med@[Link]
Exemple de web service JAX RS
@GE
T
@Path("/comptes/{code}")
@Produces(value={MediaType.APPLICATION_JSON,MediaType.APPLICATION_
XML}) public Compte getCompte(@PathParam(value="code")Long code){
return [Link](code);
}
@GE
T
@Path("/comptes")
@Produces(value={MediaType.APPLICATION_JSON,MediaType.APPLICATION_
XML}) public List<Compte> getComptes(){
return [Link]();
}
@PU
T
@Path("/comptes/verser")
public void verser(@FormParam("code") Long code,@FormParam("montant")
double montant){
[Link](code, montant);
}
med@[Link]
Exemple de web service JAX RS
@PU
T
@Path("/comptes/retirer")
public void retirer(@FormParam("code") Long
code,@FormParam("montant") double montant){
[Link](code, montant);
}
@PU
T
@Path("/comptes/virement")
@Produces(value={MediaType.APPLICATION_JSON,[Link]
_XML}) public void virement(@FormParam("cpte1") Long cpte1,
@FormParam("cpte2") Long cpte2,
@FormParam("montant") double montant){
[Link](cpte1, cpte2, montant);
}
@DELET
E
@Path("/comptes/{code}")
public void supprimer(@PathParam("code")Long code){
[Link](code);
}
}
med@[Link]
Maven Dependencies
<!-- Jersey -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>jackson-jaxrs-json-provider</
artifactId>
<version>2.3.0</version>
</dependency>
med@[Link]
Maven Dependencies
<!-- Jersey + Spring -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.8</version>
<exclusions>
<exclusion>
<groupId>[Link]</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>[Link]</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>[Link]</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>[Link]</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>[Link]</groupId>
<artifactId>spring-context</artifactId>
</exclusion>

</exclusions>
</dependency>
med@[Link]
[Link]
<!-- Jersey Container-->
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
[Link]
</servlet-class>
<init-param>
<param-name>[Link]</param-name>
<param-value>[Link]</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>

med@[Link]
Consulter les comptes avec une requête http GET

med@youssfi.
Consulter un comptes avec une requête http GET

med@[Link]
Récupérer la représentation json
d’un compte avec une requête
http GET
med@[Link]
Récupérer la représentation json
des comptes avec une requête
http GET
med@[Link]
Ajouter un compte avec requête http
POST
med@[Link]
WADL :Web Application
Description Language
 WADL est un fichier XML qui permet de
faire la description des services web
d’une application basée sur REST.
 Le WADL est généré automatiquement
par le conteneur REST.
[Link]
[Link]
 Les types de données structurés
échangés via ce web service sont
décrites par un schéma XML lié au
WSDL.
 Le schéma xml de l’application REST
peut être consulté par l’adresse de
suivante :
[Link]

med@[Link]
Récupérer le WADL

med@[Link]
Structure du DADL

med@[Link]
Structure du WADL
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="[Link]
<doc xmlns:jersey="[Link] jersey:generatedBy="Jersey: 1.8
06/24/2011 12:17 PM"/>
<resources base="[Link]
<resource path="/banque">
<resource path="/comptes">
<method id="addCompte" name="POST">
<request>
<representation mediaType="application/x-www-form-urlencoded">
<param xmlns:xs="[Link]
name="solde" style="query" type="xs:double"/>
</representation>
</request>
</method>
<method id="getComptes" name="GET">
<response>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
</response>
</method>
</resource>

med@[Link]
Structure du WADL
<resource path="/comptes/{code}">
<param xmlns:xs="[Link] name="code"
style="template" type="xs:long"/>
<method id="getCompte" name="GET">
<response>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
</response>
</method>
<method id="supprimer" name="DELETE"/>
</resource>
<resource path="/comptes/verser">
<method id="verser" name="PUT">
<request>
<representation mediaType="application/x-www-form-urlencoded">
<param xmlns:xs="[Link]
name="code" style="query" type="xs:long"/>
<param xmlns:xs="[Link]
name="montant" style="query" type="xs:double"/>
</representation>
</request>
</method>
</resource>

med@[Link]
Structure du WADL
<resource path="/comptes/retirer">
<method id="retirer" name="PUT">
<request>
<representation mediaType="application/x-www-form-urlencoded">
<param xmlns:xs="[Link]
name="code" style="query" type="xs:long"/>
<param xmlns:xs="[Link]
name="montant" style="query" type="xs:double"/>
</representation>
</request>
</method>
</resource>

med@[Link]
Structure du WADL
<resource path="/comptes/virement">
<method id="virement" name="PUT">
<request>
<representation mediaType="application/x-www-form-urlencoded">
<param xmlns:xs="[Link]
name="cpte1" style="query" type="xs:long"/>
<param xmlns:xs="[Link]
name="cpte2" style="query" type="xs:long"/>
<param xmlns:xs="[Link]
name="montant" style="query" type="xs:double"/>
</representation>
</request>
</method>
</resource>
</resource>
</resources>
</application>

med@[Link]
Client Java JaxRS

med@[Link]
Maven dependencies
<!-- Jersey Client -->
<dependencies>
<dependency>
<groupId>[Link]</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18</version>
</dependency>
<!-- Google JSON API -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
</dependencies>

med@[Link]
Code Java d’un client
JaxRS
package jerseyTest;
import [Link]; import [Link];
import [Link]; import [Link];
import [Link]; import
[Link]; import
[Link]; import
[Link];

public class RestTestClient {


public static void main(String[] args) {
ClientConfig config=new
DefaultClientConfig(); Client
client=[Link](config);
URI
uri=[Link]("[Link]
WebResource service=[Link](uri);
WebResource
path=[Link]("banque").path("comptes"); String
res=[Link]([Link]);
[Link](res); Compte[].class);
Gson gson=new GsonBuilder().create(); for(Compte cp:cptes){
Compte[] cptes=[Link](res, [Link]
n([Link]()); package jerseyTest;
} }} public class Compte {
private Long code;
private double solde;
private long dateCreation;
// Getters et Setters
}

med@youssfi.
Client HTML5,
JQUERY SGB
D

Couche DAO

Couche Métier

Service REST

HTTP
JSON

HTML, JQUERY
med@[Link]
[Link]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="jquery/[Link]"></script>
<script type="text/javascript" src="js/[Link]"></script>
</head>
<body>
<input type="button" value="charger Les comptes" onclick="chargerComptes()">
<div id="listComptes">
<table>
<thead>
<tr>
<th>Numéro</th><th>Solde</th><th>Date Création</th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
</table>
</div>
</body>
</html>
[Link]
function chargerComptes(){
$.getJSON("[Link]
$("#tableBody").html("");
for(i in data){
$tr=$("<tr>");
$td=$("<td>").append(data[i]['code']);$[Link]($td);
$td=$("<td>").append(data[i]['solde']);$[Link]($td);
$td=$("<td>").append(data[i]['dateCreation']);$[Link]($td);
$("#tableBody").append($tr);
}
});
}

med@[Link]
Client
Androïde SGB
D

Couche DAO

Couche Métier

Service WEB

HTTP
JSON

Client Mobile
Androide
med@[Link]
Vue

med@[Link]
L’activité
package [Link];
import [Link].*;import [Link].*;import
[Link].*; import
[Link];
import [Link];
import [Link].*;import [Link].*;import
[Link]; import [Link].*;import
[Link]; import [Link].*;

public class MainActivity extends Activity implements


OnClickListener { private EditText editTextMC; private Button
buttonOK;
private GridView gridViewProduits;
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
buttonOK=(Button) findViewById([Link].button1);
editTextMC=(EditText)
findViewById([Link]);
gridViewProduits=(GridView) findViewById([Link].gridView1);
[Link](this);
[Link] threadPolicy=new
[Link]().permitAll().build();
[Link](threadPolicy);
}
med@[Link]
L’activité
@Overrid
e
public void onClick(View arg0) {
[Link](getApplicationContext(), "Chargement",Toast.LENGTH_LONG).show();
StringBuilder reponseHTTP = new
StringBuilder(); HttpClient client = new
DefaultHttpClient(); String
mc=[Link]().toString();
HttpGet httpGet = new HttpGet
("[Link]
+mc); try {
HttpResponse response =
[Link](httpGet); StatusLine statusLine
= [Link](); int statusCode =
[Link]();
if (statusCode == 200) {
HttpEntity entity = [Link]();
InputStream content = [Link]();
BufferedReader reader = new BufferedReader(new
InputStreamReader(content)); String line;
while ((line = [Link]()) != null)
{ [Link](line);
}
med@[Link]
ANNOTATIONS JAXRS

med@[Link]
@Path
 Une classe Java doit être annotée par @path pour
qu’elle puisse être traitée par des requêtes HTTP
 L’annotation @path sur une classe définit des ressources
appelées racines (Root Resource Class)
 La valeur donnée à @path correspond à une expression
URI relative au contexte de l’application Web
 L’annotation @path peut également annoter des
méthodes de la classe (facultatif)
 L’URI résultante est la concaténation de l’expression du
@path de la classe avec l’expression du @path de la
méthode

[Link]

Serveur Port Context Service Opération


med@[Link]
@Path :Template Parameters

 La valeur définie dans @path ne se


limite pas seulement aux
expressions constantes
 Possibilité de définir des expressions
plus complexes appelées Template
Paramètres
 Pour distinguer une expression
complexe dans la valeur du @path, son
contenu est délimité par
{ ... }
 Possibilité également de mixer dans la
valeur de @path des expressions
constantes et des expressions
complexes
 Les Template Paramètres peuvent
également utiliser des expressions
régulières

med@[Link]
@Path :Template Parameters
package service; EXEMPLE
import [Link].*;
@Path("/biblio")
public class BookResource {
@GET
@Path("{id}")
public String getBookById(@PathParam("id") int id){
return "Book Id="+id;
}
@GET
@Path("name={name}&editor={editor}")
public String getBookByNameAndEditor(@PathParam("name") String name,@PathParam("editor") String editor){
return "Book Name="+name+" Editor="+editor;
}
}

med@[Link]
Mé́thodes HTTP : @GET, @POST, @PUT, @DELETE

 L’annotation des méthodes Java


permet de traiter de requetes HTTP
suivant le type de méthode (GET,
POST, ...)
 Les annotations disponibles par
JAX-RS sont les suivantes @GET,
@POST, @PUT, @DELETE et
@HEAD
 Ces annotations ne sont
utilisables que sur des méthodes
Java
 Le nom des méthodes Java
n’a pas d’importance puisque
c’est l’annotation employée qui
précise où se fera le traitement
med@[Link]
Mé́thodes HTTP :
@GET, @POST, @PUT,
@DELETE
 La spécification JAX-RS, n’impose pas de
respecter les conventions définies par le
style REST
 Possibilité d’utiliser une requête HTTP de
type GET pour effectuer une suppression
d’une ressource
 Des opérations CRUD sur des
ressources sont réalisées au travers
des méthodes HTTP
 Généralement :
◦ GET est utilisée pour consulter une ressource
◦ POST est utilisée pour Ajouter une nouvelle
ressource
◦ PUT est utilisée pour mettre à jour une ressource
◦ DELETE est utilisée pour supprimer une ressource

med@[Link]
Paramè̀tres de requê̂tes
 JAX-RS fournit des annotations pour
extraire des paramètres d’une requête
 Elles sont utilisées sur les paramètres des
méthodes des ressources pour réaliser
l’injection du contenu
 Liste des différentes annotations disponibles :
◦ @PathParam : extraire les valeurs des Template
Parameters
◦ @QueryParam : extraire les valeurs des paramètres de
requête
◦ @FormParam : extraire les valeurs des paramètres de
formulaire
◦ @HeaderParam : extraire les paramètres de l’entête
◦ @CookieParam : extraire les paramètres des cookies
◦ @Context : extraire les informations liées aux
ressources de contexte
 Une valeur par défaut peut être spécifiée
en utilisant l’annotation @DefaultValue
med@[Link]
L’annotation @pathparam
 L’annotation @PathParam est utilisée pour extraire les
valeurs des paramètres contenues dans les
Template Parameters

package service;
import [Link].*;
@Path("/biblio")
public class BookResource {
@GET
@Path("/bookById/{id}")
public String getBookById(@PathParam("id") int id){
return "Book Id="+id;
}
@GET
@Path("/book/name-{name}:editor-{editor}")
public String getBookByNameAndEditor(@PathParam("name") String name,@PathParam("editor") String editor){
return "Book Name="+name+" Editor="+editor;
}
}

med@[Link]
L’annotation @queryparam
 L’annotation @QueryParam est utilisée pour extraire
les valeurs des paramètres contenues d’une requête
quelque soit son type de méthode HTTP
@GET
public String getQueryParameterBook(
@DefaultValue("all")@QueryParam("name")String name,
@DefaultValue("true")@QueryParam("isReady")boolean isReady )
{ return "Name="+name+" ready="+isReady;
}

med@[Link]
Paramè̀tres de requê̂tes : @FormParam

 L’annotation @FormParam est utilisée pour extraire les


valeurs des paramètres contenues dans un formulaire
 Le type de contenu doit être :
◦ application/x-www-form-urlencoded
 Cette annotation est très utile pour extraire les
informations d’une requête POST d’un formulaire
HTML
@POST
@Path("newBook")
@Consumes("application/x-www-form-urlencoded")
public String newBook(@FormParam("name")String name){
return name +" Added";
}
med@[Link]
Paramè̀tres de requê̂tes : @Headerparam

 L’annotation @HeaderParam est utilisée pour extraire


les valeurs des paramètres contenues dans l’entête
d’une requête

@GET
public String getQueryParameterBook(
@DefaultValue("all")@QueryParam("name")String name,
@DefaultValue("true")@QueryParam("isReady")boolean isReady,
@HeaderParam("User-Agent") String userAgent ){
return "Name="+name+" ready="+isReady+" Agent="+userAgent;
}
med@[Link]
Paramètres de requê̂tes :
@Context

 L’annotation @Context permet


d’injecter des objets liés au contexte
de l’application
 Les types d’objets supportés sont les
suivants :
◦ UriInfo : informations liées aux URIs
◦ Request : informations liées au
traitement de la requête
◦ HttpHeaders : informations liées à l’entête
◦ SecurityContext : informations liées à la
sécurité
 Certainsde ces objets permettent
d’obtenir les mêmes informations que
les précédentes annotations liées aux
paramètres

med@[Link]
Paramè̀tres de requê̂tes :
@Context / UriInfo
 Un objet de type UriInfo permet
d’extraire les informations « brutes »
d’une requête HTTP
 Les principales méthodes sont les suivantes :
◦ String getPath() : chemin relatif de la requête
◦ MultivaluedMap<String, String>
getPathParameters() : valeurs des
paramètres de la requête contenues dans
Template Parameters
◦ MultivaluedMap<String, String>
getQueryParameters() : valeurs des
paramètres de la requête
◦ URI getBaseUri() : chemin de l’application
◦ URI getAbsolutePath() : chemin
absolu (base + chemins)
◦ URI getRequestUri() : chemin absolu
incluant les paramètres
med@[Link]
Paramè̀tres de requê̂tes :@Context / UriInfo
@GET
@Path("/uriInfo/{name}")
public String uriInfo(@Context UriInfo uriInfo, @PathParam("name")String name){
[Link]("getPath() :"+[Link]());
[Link]("getAbsolutePath():"+[Link]());
[Link]("getBaseUri():"+[Link]());
[Link]("ggetRequestUri():"+[Link]());
[Link]("getPathSegments():");
List<PathSegment> pathSegments=[Link]();
for(PathSegment ps:pathSegments)
[Link]([Link]());
[Link]("getPathParameters()");
MultivaluedMap<String, String> parameters=[Link]();
for(String key:[Link]())
[Link](key+"="+[Link](key));
return "OK";
}}}

med@[Link]
Paramè̀tres de requê̂tes :@Context / UriInfo

getPath() : biblio/uriInfo/a
getAbsolutePath():
[Link] getBaseUri():
[Link]
ggetRequestUri():
[Link]
getPathSegments():
biblio
uriInf
oa
getPathParameters()
name=[a]
med@[Link]
Paramè̀tres de
requê̂tes : @Context /
HttpHeaders
 Un objet de type HttpHeader permet
d’extraire les informations contenues
dans l’entête d’une requête
 Les principales méthodes sont les suivantes:
◦ Map<String, Cookie> getCookies() : les
cookies de la requête
◦ Locale getLanguage() : le langue de la requête
◦ MultivaluedMap<String, String>
getRequestHeaders() : valeurs des
paramètres de l’entête de la requête
◦ MediaType getMediaType() : le type MIME de la
requête
A noter que ces méthodes permettent
d’obtenir le même résultat que les
annotations @HeaderParam et
@CookieParam

med@[Link]
Paramè̀tres de requê̂tes :@Context /
UriInfo
@GET
@Path("httpHeaders")
public String getInformationFromHttpHeaders(@Context HttpHeaders httpheaders) {
Map<String, Cookie> cookies = [Link]();
Set<String> currentKeySet = [Link]();
for (String currentCookie : currentKeySet) {
[Link](currentCookie+"="+[Link](currentCookie));
}
MultivaluedMap<String, String> requestHeaders = [Link]();
Set<String> requestHeadersSet = [Link]();
for (String currentHeader : requestHeadersSet) {
[Link](currentHeader+"="+[Link](currentHeader));
}
return "ok";
}

• host=[localhost:8080]
• connection=[keep-alive]
• cache-control=[max-age=0]
• accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8]
• user-agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.31 (KHTML, like Gecko)
Chrome/26.0.1410.65 Safari/537.31]
• accept-encoding=[gzip,deflate,sdch]
• accept-language=[fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4]
• accept-charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.3]
med@[Link]
Repré́sentations :
@Consumes,
@Produces
 L’annotation @Consumes est utilisée pour
spécifier le ou les types MIME qu’une méthode
d’une ressource peut accepter
 L’annotation @Producer est utilisée pour
spécifier le ou les types MIME qu’une méthode
d’une ressource peut produire
 Possibilité de définir un ou plusieurs types MIME
 Ces annotations peuvent être portées sur une
classe ou sur une méthode
 L’annotation sur la méthode surcharge celle de la
classe
 Si ces annotations ne sont pas utilisées tous
types MIME pourront être acceptés ou
produits
 La
liste des constantes des différents type
MIME est disponible dans la classe
MediaType
med@[Link]
Repré́sentations :
@Consumes,
@Produces
Requête HTTP

GET /books/details/12 HTTP/1.1


Host: localhost
Accept: text/html

Type MIME accepté par le client


Reponse HTTP

HTTP/1.1 200 Type MIME de la réponse


OK
Content-Type:text/html
Date:Tue, 07 May 2013 [Link] GMT
Server:Apache-Coyote/1.1

<html>

</html>
med@[Link]
Repré́sentations : @Consumes,
@Produces
package service;
import [Link].*;
import [Link].*; @GET
import [Link]; @Path("/infos")
@Path("/banque") @Produces(MediaType.APPLICATION_JSON)
public class RestService { public List<String> getInfos(){
List<String> res=new ArrayList<String>();
@GET
[Link]("A");[Link]("B");[Link]("C");
@Path("/message")
return res;
@Produces(MediaType.TEXT_PLAIN) }
public String getMessage(){ @GET
return "Test Rest full"; @Path("/clients")
} @Produces(MediaType.APPLICATION_XML)
public List<Client> getClients(){
@GET
List<Client> res=new ArrayList<Client>();
@Path("/conversion/{montant}")
[Link](new Client(1,"A"));
@Produces(MediaType.APPLICATION_JSON) return res;
public double conversion (@PathParam("montant") double }
mt){ }
return mt*11;
}

package service;
import [Link];import [Link];
@XmlRootElement
public class Client implements Serializable {
private int code;
private String nom;
// Getters , Setters et Constructeurs
} med@[Link]
Accès au service avec un
browser

Format JSON

Format Text

Format JSON
med@[Link]
Accès au service avec un
browser

Format XML
med@[Link]
Gestion du contenu : statu des
réponses
 Lors de l’envoie de la réponse au client un code
statut est retourné
 Réponse sans erreur : Les statuts des réponses
sans erreur s’échelonnent de 200 à 399
◦ Le code est 200 « OK » pour les services retournant un
contenu non vide
◦ Le code est 204 « No Content » pour les services
retournant un contenu vide
 Réponse avec erreur : Les statuts des réponses
avec erreur s’échelonnent de 400 à 599
◦ Une ressource non trouvée, le code de retour est 404 « Not
Found »
◦ Un type MIME en retour non supporté, 406 « Not Acceptable »
◦ Une méthode HTTP non supportée, 405 « Method Not Allowed
»
med@[Link]
Response
 JAX-RS
facilite la construction de réponses en
permettant de
◦ de choisir un code de retour
◦ de fournir des paramètres dans l’entête
◦ de retourner une URI, ...
 Lesréponses complexes sont définies par la classe
Response
disposant de méthodes abstraites non utilisables
directement
◦ Object getEntity() : corps de la réponse
◦ int getStatus() : code de retour
◦ MultivalueMap<String, Object> getMetaData() : données de
l’entête
 Les
informations de ces méthodes sont
obtenues par des méthodes statiques
retournant des ResponseBuilder
 Utilisation du patron de conception Builder

med@[Link]
Principales méthodes de Response
 ResponseBuilder created(URI location) : Modifie
la valeur de Location dans l’entête, à utiliser pour
une nouvelle ressource créée
 ResponseBuilder notModified() : Statut à « Not
Modified »
 ResponseBulder ok() : Statut à « Ok »
 ResponseBuilder serverError() : Statut à « Server Error
»
 ResponseBuilder status([Link]) :
défini un statut particulier défini dans
[Link]
med@[Link]
Méthodes de ResponseBuilder

 Response build() : crée une instance de Response


 ResponseBuilder entity(Object value) :
modifie le contenu du corps
 ResponseBuilder header(String, Object) :
modifie un paramètre de l’entête

med@[Link]
Exemple de Response
@Path("response")
@GET
public Response gerReponse(){
return Response
.status([Link])
.header("param1", "valeur1")
.header("param2", "valeur2")
.entity("Corps du message")
.build();
}

med@[Link]
Exemple de Response
@GE
T
@Path("/comptes/v2/{code}")
@Produces(value={MediaType.APPLICATION_JSON,MediaType.APPLICATION_
XML}) public Response compte(@PathParam(value="code")Long code){
Compte
cp=[Link](code);
return Response
.status([Link])
.entity(cp)
.build();
}
med@[Link]
Développement Client : la
création de la requête
 La création de la requête s’appuie sur la patron Builder
 Création d’une chaine d’appel de méthodes dont le type de
retour est
WebResource ou [Link]
 La chaine d’appel se termine par les méthodes
correspondant aux méthodes HTTP (GET, POST, ...)
 La classe [Link] contient les méthodes de
terminaison
◦ <T> get(Class<T> c) : appelle méthode GET avec un type de retour T
◦ <T> post(Class<T> c, Object entity) : appelle méthode POST en
envoyant un contenu dans la requête
◦ <T> put(Class<T> c, Object entity) : appelle méthode PUT en envoyant
un contenu dans la requête
◦ <T> delete(Class<T> c, Object entity) : appelle méthode DELETE
en envoyant un contenu dans la requête
med@[Link]
Développement Client : la
création de la requête
 La classe WebResource
fournit des méthodes pour
construire l’entête de la requête
 Principales méthodes de
WebResource:
◦ WebResource path(String) : définition d’un chemin
◦ WebResource queryParam(String key, String val) : paramètre
requête
◦ Builder accept(MediaType) : type supporté par le client
◦ Builder header(String name, Object value) : paramètre entête
◦ Builder cookie(Cookie cookie) : ajoute un cookie

 Possibilité d’appeler plusieurs


fois la même méthode
med@[Link]
Exemple de Client java REST
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class ClientJaxRS {
public static void main(String[] args) {
ClientConfig config=new DefaultClientConfig();
Client client=[Link](config);
URI uri=[Link]("[Link]
WebResource service=[Link](uri);
WebResource path=[Link]("banque").path("conversion").path("5");
String res=[Link]([Link]);
[Link](res);
}
}

med@[Link]
Client java REST: Méthodes POST et PUT

// Requête POST avec un paramètre


WebResource path2=[Link]("banque").path("comptesParClient").queryParam("cc","45");
String res2=[Link]([Link]);
[Link](res2);
// Requête PUT pour envoyer un objet Client
WebResource path3=[Link]("banque").path("newClient");
String res3=[Link]([Link],new [Link](3, "ABC"));
[Link](res3);

package service;
import [Link];
import [Link];
@XmlRootElement
public class Client implements Serializable {
private int code;
private String nom;
// Constructeurs, Getters et Setters
}
med@[Link]
Client java REST:
ClientResponse

[Link](" ");
WebResource path4=[Link]("banque").path("response");
ClientResponse res4=[Link]([Link]);
MultivaluedMap<String, String> headers=[Link]();
[Link]([Link]("param1"));
[Link]([Link]("param2"));
[Link]([Link]([Link]));
med@[Link]
Problème
 On souhaite Créer une application distribuée qui
permet de gérer le transport des cargaisons
contenant des marchandises. Chaque cargaison
contient plusieurs marchandises. Il existe deux
types de cargaisons : les cargaisons routières et
aériennes.
 Chaque marchandise est définie par un numéro
de type Long (Auto Incrémenté), le nom de la
marchandise, son poids et son volume.
 Chaque cargaison est définie par une
référence de type String, la distance de
parcours, la date de livraison.
 Une cargaison routière est une cargaison qui
possède en plus la température de conservation.
 Une cargaison aérienne est une cargaison qui
possède en plus un poids maximal qui ne doit
pas être dépassé.
med@[Link]
Problème
 L’application se compose de des couches suivantes :
 Une couche métier basées sur EJB (Entity et Session)
 Une couche service qui permet un accès distant
aux services métiers qui contient deyx types de
services :
◦ Un web service SOAP avec JAXWS
◦ Un web service REST FULL basé sur JAXRS
 Pour accéder aux services de cette application,
d’autres entreprises peuvent développer des
applications clientes de différents types :
◦ Un client Mobile Androide
◦ Un client PHP qui permet de consulter les marchandises dont le
nom contient un mot clé. Cette application fait appel à la
couche métier via le service SOAP
◦ Un client Java qui permet d’ajouter les cargaisons et les
marchandises en faisant appel au service REST FULL (Format
généré : JSON)
◦ Un client WEB (HTML, CSS, JQUERY) qui permet de consulter les
marchandises d’une cargaison sélectionnée dans une liste
déroulante. Cette application s’appuie sur le service REST FULL
med@[Link]
Architecture
Seveur d’application J2EE : JBOSS MYSQL
(http :8080)

Couche Couche Proxy AXIS Data Web Browser


Métier JPA Sour HTML, JQuery
EJB Entity ces
EntityManag
EJB er
Session

Couche Hiberna
Service Web te JDBC
Service SOAP
Web Service JNDI
REST

HTT
HTTP P
JSON JSO
N
Client Java
Client Android
he :8888
Apa PHP
SOAP
c
HTTP

med@[Link]
Diagramme de classes

med@[Link]
Base de données
 Démarrer Easy PHP
◦MySQL
◦Apache
◦PHP
◦PhpMyAdmin
 Créer la base de
données
DB_TRANSPORT
 Les tables seront créées par le
framework de mapping objet
relationnel (Hibernate)
med@[Link]
Déployer le DataSource

<datasource jndi-name="java:/dsTR" pool-name="dsTR" enabled="true">


<connection-url>jdbc:mysql://[Link]:3306/DB_TRANSPORT</
connection-url>
<driver-class>[Link]</driver-class>
<driver>mysql</driver>
<security>
<user-name>root</user-name>
</security>
</datasource>

med@[Link]
Projet Web Dynamique

med@[Link]
Structure du projet

med@[Link]
Entity : Marchandise
package [Link]; import [Link]; import
[Link].*; @Entity
@Table(name="MARCHANDISES")
public class Marchandise implements
Serializable { @Id
@GeneratedValue(strategy=[Link]
TY) @Column(name="NUMERO")
private Long numero;
@Column(name="NOM")
private String nom;
private double poids;
private double volume;
@ManyToOne
@JoinColumn(name="REF_CARG")
private Cargaison cargaison;
public Marchandise(String nom, double poids, double
volume) { [Link] = nom;[Link] = poids; [Link]
= volume;
}
public Marchandise() {super(); }
// Geters et Setters
} med@[Link]
Entity : Cargaison
package [Link];import [Link].*;import
[Link].*; import [Link].*;import
[Link].*; import
[Link];
@Entity
@Table(name="CARGAISONS")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE_CARG")
@XmlAccessorType([Link])
@XmlSeeAlso({[Link],[Link]
}) public abstract class Cargaison implements Serializable{
@Id
@Column(name="REF_CARG"
)
private String reference; private int distance; private Date
dateLivraison; @OneToMany(mappedBy="cargaison",fetch=[Link])
@XmlTransient
private Collection<Marchandise> marchandises;
public Cargaison(String reference, int distance, Date dL) {
[Link] = reference; [Link] = distance; [Link] = dL;
} public Cargaison()
{} @JsonIgnore
public Collection<Marchandise> getMarchandises() { return marchandises;} //Get et
Set}
Entity : CargaisonAerienne
package [Link];
import [Link];
import
[Link].*;
@Entity
@DiscriminatorValue("CA")
public class CargaisonAerienne extends
Cargaison { private double poidsMax;
public CargaisonAerienne(String reference, int distance, Date
dateLivraison, double poidsMax) {
super(reference, distance,
dateLivraison); [Link] = poidsMax;
}
public CargaisonAerienne() {
}

// Getters et Setters
}
Entity : CargaisonRoutiere
package [Link];
import [Link];
import
[Link].*;
@Entity
@DiscriminatorValue("CR")
public class CargaisonRoutiere extends
Cargaison { private float
temperatureConservation;
public CargaisonRoutiere(String reference, int distance, Date
dateLivraison, float temperatureConservation) {
super(reference, distance, dateLivraison);
[Link] = temperatureConservation;
}

public CargaisonRoutiere() {
}
// Getters et Setters
}
[Link]
Le dossier META-INF devrait être ajouté au classpath :

<?xml version="1.0" encoding="UTF-8"?>


<persistence
xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
ence
[Link]
.xsd" version="1.0">
<persistence-unit name="UP_TRANSPORT">
<jta-data-source>java:/dsTRANSPORT</jta-data-source>
<properties>
<property name="[Link]" value="update"/>
</properties>
</persistence-unit>
</persistence>
Déployer le projet
Les deux tables CAGAISONS et
MARCHANDISES de la bases de
données devraient être générées:
MRCHANDISES :

CAGAISONS :

med@[Link]
Traitements Métier
 Interface Local

package
[Link];
import [Link];
import [Link];
@Local
public interface ITransportLocal {
public void addCargaison(Cargaison
c);
public void addMarchandise(Marchandise m,String
refCarg); public List<Cargaison> getAllCargaisons();
public List<Marchandise> getMarchandisesParCarg(String
refCarg); public Cargaison getCargaison(String reg);
public void supprimerMarchandise(Long numeroMarch);
}
med@[Link]
Traitements Métier
 EJB Session Statless
package [Link];import [Link];
import [Link];import
[Link].*; @Stateless(name="TRANS")
public class TransportEJBImpl implements ITransportLocal {
@PersistenceContext(unitName="UP_TRANSPORT")
EntityManager em;
@Override
public void addCargaison(Cargaison c)
{ [Link](c);
}
@Override
public void addMarchandise(Marchandise m, String refCarg) {
Cargaison c=[Link]([Link], refCarg);
[Link](c);[Link](m);
}
@Override
public List<Cargaison> getAllCargaisons() {
Query req=[Link]("select c from Cargaison
c"); return [Link]();
} med@youssfi.
Traitements Métier
 EJB Session Statless
@Override
public List<Marchandise> getMarchandisesParCarg(String refCarg)
{
Query req=[Link]
("select m from Marchandise m where [Link]=:x");
[Link]("x", refCarg);
return [Link]();
}
@Override
public Cargaison getCargaison(String
reg) { Cargaison
c=[Link]([Link], reg); return
c;
}
@Override
public void supprimerMarchandise(Long numeroMarch) {
Marchandise m=[Link]([Link],
numeroMarch); [Link](m);
}
}
med@[Link]
Couche Service

med@[Link]
Web Service SOAP
package [Link];import [Link].*;
import [Link].*;import [Link].*;import [Link].*;
@Stateless
@WebService
public class TransportSOAPService
{ @EJB
private ITransportLocal
metier; @WebMethod
public void ajouterCargaisonRoutiere(
@WebParam(name="ref")String ref,
@WebParam(name="distance")int dist,
@WebParam(name="dateLivraison")Date dateLiv,
@WebParam(name="tempConserv")float temp){
CargaisonRoutiere cr=new CargaisonRoutiere(ref, dist, dateLiv, temp);
[Link](cr);
}

med@[Link]
Web Service SOAP
@WebMethod
public void ajouterCargaisonAerienne(
@WebParam(name="ref")String ref,
@WebParam(name="distance")int dist,
@WebParam(name="dateLivraison")Date dateLiv,
@WebParam(name="poidsMax")float poids){
CargaisonAerienne ca=new CargaisonAerienne(ref, dist, dateLiv, poids);
[Link](ca);
}
@WebMethod
public void ajouterMarchandise(
@WebParam(name="nom")String nom,
@WebParam(name="poids")double poids,
@WebParam(name="volume")double volume,
@WebParam(name="refCarg")String refCarg){
Marchandise m=new Marchandise(nom, poids, volume);
[Link](m, refCarg);
}

med@[Link]
Web Service SOAP
@WebMethod
public List<Cargaison>
getAllCargaisons(){ return
[Link]();
}
@WebMethod
public List<Marchandise> getMarchParCarg(
@WebParam(name="refCarg")String refCarg){
return
[Link](refCarg);
}
@WebMethod
public Cargaison consulterCargaison(
@WebParam(name="refCarg")String refCarg){
return [Link](refCarg);
}
@WebMethod
public void supprimerMarchandise(
@WebParam(name="numMarch")Long
numero){
[Link](numero);
}}
med@[Link]
Redéployer le projet
 WSDL

med@[Link]
Tester les méthodes avec le
client SOAP Oxygen

med@youssfi.
Requête SOAP pour ajouter les
cargaisons et les marchandises
<SOAP-ENV:Envelope xmlns:SOAP-
ENV="[Link]
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ajouterCargaisonRoutiere xmlns="[Link]
<ref xmlns="">CR2</ref>
<distance xmlns="">120</distance>
<dateLivraison xmlns="">2011-12-11</dateLivraison>
<tempConserv xmlns="">22</tempConserv>
</ajouterCargaisonRoutiere>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

med@[Link]
Requête SOAP pour ajouter les
cargaisons et les marchandises
<SOAP-ENV:Envelope xmlns:SOAP-ENV="[Link]
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ajouterCargaisonAerienne xmlns="[Link]
<ref xmlns="">CA2</ref>
<distance xmlns="">123</distance>
<dateLivraison xmlns="">2012-12-13</dateLivraison>
<poidsMax xmlns="">200</poidsMax>
</ajouterCargaisonAerienne>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

med@[Link]
Requête SOAP pour consulter toutes les cargaisons
<SOAP-ENV:Envelope xmlns:SOAP-ENV="[Link]
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<getAllCargaisons xmlns="[Link]
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

<soap:Envelope xmlns:soap="[Link]
<soap:Body>
<ns2:getAllCargaisonsResponse xmlns:ns2="[Link]
<return xmlns:xsi="[Link]
instance" xsi:type="ns2:cargaisonAerienne">
<reference>CA1</reference>
<distance>700</distance>
<dateLivraison>2012-11-12T[Link]Z</dateLivraison>
<poidsMax>500.0</poidsMax>
</return>
<return xmlns:xsi="[Link]
instance" xsi:type="ns2:cargaisonRoutiere">
<reference>CR1</reference>
<distance>900</distance>
<dateLivraison>2012-11-11T[Link]Z</dateLivraison>
<temperatureConservation>22.0</temperatureConservation>
</return>
</ns2:getAllCargaisonsResponse>
</soap:Body>
</soap:Envelope>
med@youssfi.
Requête SOAP pour consulter toutes les
marchandises d’une cargaison
<SOAP-ENV:Envelope xmlns:SOAP-ENV="[Link]
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<getMarchParCarg xmlns="[Link]
<refCarg xmlns="">CA1</refCarg>
</getMarchParCarg>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

<soap:Envelope xmlns:soap="[Link]
<soap:Body>
<ns2:getMarchParCargResponse xmlns:ns2="[Link]
<return>
<cargaison xmlns:xsi="[Link]
xsi:type="ns2:cargaisonAerienne">
<reference>CA1</reference>
<distance>700</distance>
<dateLivraison>2012-11-12T[Link]Z</dateLivraison>
<poidsMax>500.0</poidsMax>
</cargaison>
<nom>PC</nom>
<numero>1</numero>
<poids>22.0</poids>
<volume>66.0</volume>
</return>
<return> …… </return>
</ns2:getMarchParCargResponse>
</soap:Body>
</soap:Envelope>
med@youssfi.
Web Service REST FULL
package [Link];import [Link]; import
[Link]; import [Link].*; import [Link].*;
import [Link]; import
[Link].*; @Stateless
@Path("/transport")
public class TransportRESTService {
// Injection des dépendances
@EJB
private ITransportLocal metier;
// Méthode pour ajouter une cargaison
routière @GET
@Path("addCargRoutiere/{ref}/{dist}/{dateLiv}/{temp}")
@Produces(MediaType.APPLICATION_JSON)
public void ajouterCargaisonRoutiere(
@PathParam(value="ref")String ref, @PathParam(value="dist")int
dist,
@PathParam(value="dateLiv")Date dateLiv,
@PathParam(value="temp")float temp){
CargaisonRoutiere cr=new CargaisonRoutiere(ref, dist, dateLiv, temp);
[Link](cr);
} med@[Link]
Web Service SOAP
// Méthode pour ajouter une cargaison
Aérienne @GET
@Path("addCargAerienne/{ref}/{dist}/{dateLiv}/{poids}")
@Produces(MediaType.APPLICATION_JSON)
public void ajouterCargaisonAerienne(
@PathParam(value="ref")String ref, @PathParam(value="dist")int dist,
@PathParam(value="dateLiv")Date dateLiv, @PathParam(value="poids")float poids){
CargaisonAerienne ca=new CargaisonAerienne(ref, dist, dateLiv, poids);
[Link](ca);
}
// Méthode pour ajouter une
marchandise @GET
@Path("addMarch/{nom}/{poids}/{volume}/
{refCag}")
@Produces(MediaType.APPLICATION_JSON)
public void ajouterMarchandise(
@PathParam(value="nom")String nom, @PathParam(value="poids")double poids,
@PathParam(value="volume")double volume, @PathParam(value="refCarg")String
refCarg){ Marchandise m=new Marchandise(nom, poids, volume);
[Link](m, refCarg);
}

med@[Link]
Web Service SOAP
// Méthode pour consulter toutes les
cargaisons @GET
@Path("allCarg")
@Produces(MediaType.APPLICATION_JSON)
public List<Cargaison>
getAllCargaisons(){
return [Link]();
}
// Méthode pour consulter les marchandises d’une
cargaison @GET
@Path("marchandises/{refCarg}")
@Produces(MediaType.APPLICATION_JSON)
public List<Marchandise>
getMarchParCarg( @PathParam(value="refC
arg")String refCarg){
return [Link](refCarg);
}
med@[Link]
Web Service SOAP
// Méthode pour consulter une
cargaison @GET
@Path("consulterCargaison/
{refCarg}")
@Produces(MediaType.APPLICATION_J
SON) public Cargaison
consulterCargaison(
@PathParam(value="refCarg")String
refCarg){ return
[Link](refCarg);
}
// Méthode pour supprimer une
marchandise @GET
@Path("supprimerMarch/{num}")
@Produces(MediaType.APPLICATION_JSO
N) public void supprimerMarchandise(
@PathParam(value="num")Long numero){
[Link](numero);
}
}
med@[Link]
Application REST FULL
package [Link];
import
[Link];
import
[Link];
@ApplicationPath("/")
public class TransportRestApp extends Application {

}
med@[Link]
Tester le service REST

med@[Link]
Client Java, JSP Via un Proxy
SOAP
 Créer un Projet Web Dynamique
med@[Link]
Générer un Proxy pour l’accès
au service SOAP
 Créer un client Web Service

med@youssfi.
Générer un Proxy pour l’accès
au service SOAP
 Spécifier l’adresse du WSDL

med@youssfi.
Générer un Proxy pour l’accès
au service SOAP
 L’assistant est prêt à générer le code dans le dossier
src
med@[Link]
Proxy Généré

med@[Link]
Client Java Lourd
package clientSOAP; import [Link]; import
[Link].*; import [Link].*;
public class ClientLourd {
public static void main(String[]
args) { try {
TransportSOAPServiceProxy stub=new TransportSOAPServiceProxy();
[Link]("CA4", 600, [Link](), 800);
[Link]("CR4", 200, [Link](), 22);
[Link]("Ordinateurs", 900, 56, "CA4");
Cargaison[] cargs=[Link]();
[Link]("---- Totes Les cargaison---");
for(Cargaison c:cargs){
[Link]([Link]()
+"--"+[Link]()+"--
"+[Link]().getSimpleName());
}
[Link]("--- Marchandises d'une cargaison ---");
Marchandise[] marchandises=[Link]("CA1");
for(Marchandise m:marchandises){
[Link]([Link]()+"--"+[Link]()+"--"+[Link]());
}} catch (RemoteException e) { [Link](); } } }
Exécution du client Lourd
---- Totes Les
cargaison--- CA1--700--
CargaisonAerienne CA2--
123--CargaisonAerienne
CA4--600--
CargaisonAerienne CR1--
900--CargaisonRoutiere
CR2--120--
CargaisonRoutiere CR4--
200--CargaisonRoutiere
--- Marchandises d'une cargaison
--- PC--22.0--66.0
Imprimantes--23.0--88.0

med@[Link]
Client Web JSP
<%@page import="[Link].*"%>
<%@page import="[Link]"%>
<%
TransportSOAPServiceProxy stub=new TransportSOAPServiceProxy();
Cargaison[]
cargs=[Link]();
Marchandise[] mdises=new Marchandise[0];
String refCarg=null;
if([Link]("action")!=null){
String
action=[Link]("action");
if([Link]("marchandises")){
refCarg=[Link]("refCarg");
mdises=[Link](refCarg);
}
}
%>
med@[Link]
Client Web JSP
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="[Link]" method="get">
Cargaisons:
<select name="refCarg">
<option>------</option>
<% for(Cargaison c:cargs) {%>
<option value="<%=[Link]()%>"
<%if([Link]().equals(refCarg)){ %> selected="selected" <%} %> >
<%=[Link]()%>
</option>
<%} %>
</select>
<input type="submit" name="action" value="marchandises">
</form>
med@[Link]
Client Web JSP
<table border="1" width="80%">
<tr>
<th>Num</th><th>Nom</th><th>Poids</th><th>Volume</th>
</tr>
<% for(Marchandise m:mdises){%>
<tr>
<td><%=[Link]()%></td><td><%=[Link]()%></td><td>
<%=[Link]()%></td><td><%=[Link]() %></td>
</tr>
<%} %>
</table>
</body>
</html>

med@[Link]
Client Web Ajax JQuery
 Créer un Projet Web Statique
 Copier le framework Jquery :
◦ [Link]

med@[Link]
[Link]
<html>
<head>
<script language="javascript" src="jquery/[Link]"></script>
<script language="javascript" src="jquery/[Link]"></script>
<script language="javascript" src="jquery/[Link]"></script>
<link rel="stylesheet" type="text/css" href="jquery/[Link]" />
</head>
<body onload="chargerCarg()">
<div>
Cargaisons :
<table border="1" width="80%">
<thead>
<tr><th>REF CARG</th><th>DATE LIVRAISON</th>
<th>DISTANCE</th><th>Type</th><th>Poids Max</th><th>Temp Cons</th>
</tr>
</thead>
<tbody id="cargaisons">
</tbody>
</table>

med@[Link]
[Link]
<p></
p>
<table border="1" width="80%">
<thead>
<tr>
<th>Numéro</th><th>Nom</th><th>Poids</th><th>Volume</
th>
</tr>
</thead>
<tbody id="tableBody">

</tbody>
</table>
</div>
</body>
</html>
med@[Link]
Code Java Script avec Jquery : [Link]
function chargerCarg(){
$.getJSON('/TP_TRANSPORT/transport/consulterCarg',

function(data){ filieres=data;
for(i in data){
$tr=$("<tr>");
$lien=$("<a>").append(data[i]
['reference']).attr("href","javascript:chargerMarchan dises('"+data[i]
['reference']+"')");
$td=$("<td>").append($lien);$[Link]($td);
$td=$("<td>").append(data[i]['dateLivraison']); $[Link]($td);
$td=$("<td>").append(data[i]['distance']);
$[Link]($td); var type=(data[i]
['poidsMax']==null)?"Aérienne":"Routière";
$td=$("<td>").append(type); $[Link]($td);
$td=$("<td>").append(data[i]['poidsMax']); $[Link]($td);
$td=$("<td>").append(data[i]['temperatureConservation']); $[Link]($td);
$("#cargaisons").append($tr);
}
}
);
}
med@[Link]
Code Java Script avec Jquery : [Link]
function chargerMarchandises(refCarg){
$.getJSON('/TP_TRANSPORT/transport/
consulterMarchParCarg/'+refCarg, function(data){
filieres=data;
for(i in data)
{
$tr=$("<tr>");
$td=$("<td>").append(data[i]['numero']); $[Link]($td);
$td=$("<td>").append(data[i]['nom']); $[Link]($td);
$td=$("<td>").append(data[i]['poids']); $[Link]($td);
$td=$("<td>").append(data[i]['volume']); $[Link]($td);
$("#tableBody").html("");
$("#tableBody").append($tr);
}
}
);
}
med@[Link]
Aperçu du client JQuery

med@[Link]
JQuery
Les premiers « Frameworks »
 JavaScript a été créé pour améliorer l’interactivité entre les
utilisateurs et les page HTML.
 Avec une grande maitrise de JavaScript, associé au CSS, on
peut créer des interfaces graphique web performantes de
très grande qualité.
 Les développeurs professionnels JavaScript ont capitalisé
leurs expériences en créant des bibliothèques JavaScript qui
permettent de faciliter la tâche aux développeurs web.
 Beaucoup de « Frameworks » JavaScript, on vu leurs
naissances :
◦ PrototypeJS : [Link]
◦ Mootools : [Link]
◦ DoJo Toolkit : [Link]
◦ Yahoo UI : [Link]/yui/
◦ ExtJS : [Link]
◦ UIZE : [Link]
◦ Spry : [Link]
◦ JQuery
med@[Link] 316
JQuery
 Une bibliothèque javascript open-source
 Elle permet de traverser et manipuler très
facilement l'arbre DOM des pages web à
l'aide d'une syntaxe simplifiée.
 JQuery permet par exemple
◦ de changer/ajouter une classe CSS,
◦ créer des animations,
◦ Afficher des widgets (Menus, Panneaux à onglets etc..)
◦ modifier des attributs,
◦ Gérer les événements javascript
◦ Envoyer des requêtes HTTP AJAX aux serveurs Web
◦ ….

med@[Link] 317
une simple bibliothèque à
importer
 Disponible sur le site de Jquery
[Link]
<script src="[Link]"></script>
 Ou directement sur Google code
<script type="text/javascript" src=
"[Link]
</script>
med@[Link] 318
JavaScript / jQuery
 Masquer tous les div du
document HTML avec JavaScript
pur:
divs =
[Link]('div');
for (i = 0; i < [Link]; i++)
{ divs[i].[Link] = 'none';
}
 Faire la même chose avec jQuery :
$("div").hide();
med@[Link] 319
La fonction jQuery()
 jQuery repose sur une seule
fonction : jQuery() ou $().
 C’est une fonction JavaScript
 Elle accepte des paramètres
 Elle retourne un objet
 $ : Syntaxe issue du framework
« Prototype »

med@[Link] 320
Les sélecteurs d’éléments: $
('anything')
$ accepte des ID :
◦ $('#nomID') retourne un élément sachant sont id
◦ Equivalent javascript :
 [Link]('nomID')
$ accepte des classes css :
◦ $('.nomClasse') : retourne tous les éléments qui
correspondent à cette classe
◦ Equivalent javascript :
 [Link]('nomClasse')
$ accepte plusieurs sélecteurs
◦ $('#article, .nouvelles, a')
◦ Permet de sélectionner les éléments suivants:
 L’élément dont id est article
 les éléments ayant la classe css nouvelles
 Les liens hypertexte (a)
med@[Link] 321
Les sélecteurs d’éléments: $
('anything')
 $(document)
◦ Extension de l'objet document à la classe jQuery.
 $('*')
◦ Sélectionne tous les éléments.
 $('#monDiv')
◦ Sélectionne l'élément ayant l'ID "monDiv".
 $('[Link]')
◦ Sélectionne les éléments <p> ayant la classe
"first".
 $('p[title]')
◦ Sélectionne les éléments <p> ayant un attribut
"title".
med@[Link] 322
Les sélecteurs d’éléments: $
('anything')
 $('p[title="Bonjour"]')
◦ Sélectionne les éléments <p> dont l'attribut title
est "Bonjour".
 $('p[title!="Bonjour"]')
◦ Sélectionne les éléments <p> dont l'attribut
title n'est pas "Bonjour".
 $('p[title^="H"]')
◦ Sélectionne les éléments dont l'attribut title
commence par "H".
 $('p[title$="H"]')
◦ Sélectionne les éléments dont l'attribut title fini par
"H".
med@[Link] 323
Les sélecteurs d’éléments: $
('anything')
 $('p[title*="H"]')
◦Sélectionne les éléments dont
l'attribut title contient "H".
 $('ul, ol, dl')
◦Sélectionne les éléments <ul>, <ol> et
<dl>
 $('div .desc')
◦Sélectionne les éléments ayant la
classe "desc" descendants (au sens
CSS) d'éléments <div>.
med@[Link] 324
Les sélecteurs d’éléments: $
('anything')
 $('div > .enfant')
◦ Sélectionne les éléments ayant la classe
"enfant" enfants d'éléments <div>.
 $('label + input')
◦ Sélectionne les éléments <input /> dont l'élément
précédent (dans le DOM) est <label>.
 $('#debut ~ div')
◦ Sélectionne les éléments <div> frères se situant
après l'élément dont l'id est "debut".
med@[Link] 325
Filtrer les sélections
 jQuery offre une très large
possibilité de sélection
d'éléments en fonction de filtres
sur des collections d'éléments.
 Le fonctionnement de la
sélection par filtre est simple : on
sélectionne d'abord un ensemble
d'éléments (par défaut, tous) puis
on affine cette sélection à partir
de certains critères.
med@[Link] 326
Filtrer les sélections
 $('div:first')
◦ Sélectionne le premier élément <div>.
 $('div:last')
◦ Sélectionne le dernier élément <div>.
 $('div:not(.ok)')
◦ Sélectionne les <div> n'ayant pas la classe "ok".
 $('div:[even|odd]')
◦ Sélectionne les éléments <div> de rang [pair|
impair] (le premier rang est 0).
 $('div:[eq|lt|gt](n)')
◦ Sélectionne le ou les éléments
<div> de rang [égal|inférieur|
supérieur] à n.

med@[Link] 327
Filtrer les sélections
 $(':header')
◦ Sélectionne les éléments <hn>.
 $(':animated')
◦ Sélectionne les éléments actuellement animés.
 $("div:contains('dvp')")
◦ Sélectionne les éléments <div> contenant le
texte "dvp" (sensible à la casse !)
 $('div:empty')
◦ Sélectionne les éléments <div> vides.
 $('div:has(p)')
◦ Sélectionne les éléments <div> ayant un descendant
<p>.

med@[Link] 328
Filtrer les sélections
 $('div:parent')
◦ Sélectionne les éléments <div> ayant des enfants.
 $('div:nth-child([n|even|odd|
equation])')
◦ // Les enfants de <div> [de rang n|pairs|impairs|
résultat de].
 $('div:[first-child|last-child]')
◦ Les éléments [premier|dernier] enfants d'un élément
<div>.
 $('div:only-child')
◦ Les éléments qui sont les seuls enfants d'un élément
<div>.
med@[Link] 329
Les éléments de formulaires
 $(':input')
◦ Tous les éléments <input />, <textarea>, <select> et
<button>.
 $(':[text|password|radio|checkbox|submit|imag
e|reset|button|file|hidden]')
◦ Les <input> du type choisi.
 $(':[enabled|disabled|checked|selected]')
◦ Les <input /> possédant l'attribut indiqué.

med@[Link] 330
Exemple
<html>
<script type="text/javascript"
src="[Link]">
</script>
<body>
<div id="monDiv">Bonjour</div>
<a href="#" onClick="$('#monDiv').hide();">
disparition</a>
</body>
</html>

med@[Link] 331
Méthodes de l’objet jQuery
 Lesméthodes s'appliquent généralement à tous
les éléments sélectionnés
◦ $('.classe').hide(); $('.classe').show();
◦ $('.classe').slideUp();$('.classe').slideDown();

 De nombreuses méthodes utilitaires


◦ parcourir le DOM:
 find("elements") :Recherche les éléments répondant
aux conditions du sélecteur spécifié. Cette méthode est
utile pour retrouver les éléments descendant d'un élément
donné.
 parent() : retourne l’élément parent de la sélection
 next() : retourne l’élément suivant de la sélection
 children() : retourne l’élément fils de chaque élément de la
sélection
 parents() : Retourne la liste des éléments contenant
les ancêtres des éléments recherchés
med@[Link] 332
Méthodes de l’objet jQuery
◦ Gérer les styles CSS:
 addClass('nomClasse') : Ajouter une classe aux éléments de la
sélection
 removeClass('nomClasse') : Supprimer une classe aux
éléments de la sélection
 css('attributCSS', 'valeur') : permet de modifier les
styles CSS aux éléments sélectionnés
◦ manipuler:
 append(html) : permet d’ajouter du contenu html aux
éléments de la sélection.
 wrap(html): Entoure une structure d'élements par d'autres
éléments
 repend(html) : Ajoute du contenu à l'intérieur des
éléments sélectionnés, au début.
 attr('nomAttribut', 'valeur') : permet de modifier la
valeur d’un attribut des éléments sélectionnés
 Intérêt fondamental: la plupart des méthodes de
l'objet retournent l'objet lui-même
◦ on peut chaîner les appels !
◦ $('anything').parent().find('still
anything').show();
med@[Link] 333
Utilisation des sélecteurs et
des événements
 JQuery nous propose 2
approches afin de sélectionner
des éléments.
◦La première utilise une
combinaison de sélecteurs CSS et
XPath passés comme chaîne de
caractères au constructeurjQuery
(comme par exemple $("div>ul
a")).
◦La seconde méthode se sert de
différentes fonctions de l'objet
jQuery.
 Les deux approches
peuvent être combinées.

med@[Link] 334
Utilisation des sélecteurs et
des événements
 Au chargement document html :
$(document).ready (
function(){
// Code à exécuter au chargement de la page
}
);
 Ou encore :
$(
function(){
// Code à exécuter au chargement de la page
}
);

med@[Link] 335
Exemple 2:
$(document).ready( function()
{
$("#valider").click( function()
{
$("#form").submit();
}
);
}
);

 Le code précédent permet, quand on


click sur le bouton valider, de
sélectionner l'élément ayant l'id
« form » et appelle sa méthode submit()
med@[Link] 336
Widgets et Effets Jquery
[Link]
 Après les interactions, il va
falloir nous lancer dans les
widgets de jQuery UI.
 Ce sont des plugins plus
orientés dans le confort des
utilisateurs.
 De même, la librairie met à
disposition des effets
complémentaires, introuvables
dans jQuery, et qui sont
vraiment très sympathiques.
med@[Link] 337
Fichiers à inclure dans l’entête de la
page HTML
<head>
<link rel="stylesheet" href="jquery-
[Link]" />
<script src="[Link]"></script>
<script src="[Link]"></script>
</head>
med@[Link] 338
Création d’un accordéon

med@[Link] 339
Structure d’un accordéon
jQuery
 Structure d’un accordellon JQuery (Code HTML)
<div id="accordeon">
<h3>Section1</h3>
<div>Contenu Section 1</div>
<h3>Section2</h3>
<div>Contenu Section 2</div>
<h3>Section3</h3>
<div>Contenu Section 3</div>
</div>
 Comportement de l’accordéon (Code Java Scrit) :
<script language="javascript">
$(function(){
$("#accordeon").accordion();
})
</script>
 Pour Que la section 2 soit active au début au lieu de la première :

$("#accordeon").accordion({active:1});
med@[Link] 340
Code Complet de la page
<html>
<head>
<title>Accordéon JQuery</title>
<script type="text/javascript" src="[Link]"></script>
<script type="text/javascript" src="[Link]"></script>
<link rel="stylesheet" type="text/css" href="[Link]" />
</head>
<body>
<div id="accordeon">
<h3>Section1</h3>
<div>Contenu Section 1</div>
<h3>Section2</h3>
<div>Contenu Section 2</div>
<h3>Section3</h3>
<div>Contenu Section 3</div>
</div>
<script language="javascript">
$(function(){
$("#accordeon").accordion();
})
</script>
</body>
</html>

med@[Link] 341
Une autre manière pour créer
l’accordéon
 Structure d’un accordellon JQuery (Code HTML)
<ul id="accordeon2">
<li class="titre">Section 1</li>
<li>Contenu de la section 1</li>

<li class="titre">Section 2</li>


<li>Contenu de la section 2</li>

<li class="titre">Section 3</li>


<li>Contenu de la section 3</li>
</ul>
 Comportement de l’accordéon (Code Java Scrit) :
<script language="javascript">
$(function(){
$("#accordeon2").accordion({header:'.titre'});
})
</script>
med@[Link] 342
Code Complet de la page
<html>
<head>
<title>Accordéon JQuery</title>
<script type="text/javascript" src="[Link]"></script>
<script type="text/javascript" src="[Link]"></script>
<link rel="stylesheet" type="text/css" href="[Link]" />
<style>
.titre{
background:#FFCCCC;
} med@
</style> youssf
</head> [Link]
<body>
<ul id="accordeon2">
<li class="titre">Section 1</li>
<li>Contenu de la section 1</li>
<li class="titre">Section 2</li>
<li>Contenu de la section 2</li>
<li class="titre">Section 3</li>
<li>Contenu de la section 3</li>
</ul>
<script language="javascript">
$(function(){
$("#accordeon2").accordion({header:'.titre'});
});
</script>
</body>
</html>
343
Panneau à Onglets
 Structure : (HTML)
<div id="tabs">
<ul>
<li><a href="#tabs-1">Tab1</a></li>
<li><a href="#tabs-2">Tab2</a></li>
<li><a href="#tabs-3">Tab3</a></li>
</ul>
<div id="tabs-1"> Contenu Tab1</div>
<div id="tabs-2">Contenu Tab2</div>
<div id="tabs-3">Contenu Tab3 </div>
</div>

 Comportement : (JavaScript)
<script language="javascript">
$(function(){
$("#tabs").tabs());
})
</script>

med@[Link] 344
Menu déroulant
 Structure : (HTML)
<ul id="menu">
<li class="ui-state-disabled"><a href="#">XML</a></li>
<li><a href="#">HTML</a></li>
<li><a href="#">CSS</a></li>
<li><a href="#">Java SCript</a></li>
<li><a href="#">Programmation</a>
<ul>
<li class="ui-state-disabled"><a href="#">Ada</
a></
<li><a href="#">Java</a></li>
<li><a href="#">C++</a></li>
</ul>
</li>
<li><a href="#">Multimédia</a></li>
</ul>
 Comportement : (JavaScript)
<script language="javascript">
$(function(){
$( "#menu" ).menu();
})
</script>

med@[Link] 345
DatePicker : Calendrier

med@[Link] 346
DatePicker
<html>
<head>
<title>Date Picker</title>
<script type="text/javascript" src="[Link]"></script>
<script type="text/javascript" src="[Link]"></script>
<link rel="stylesheet" type="text/css" href="[Link]" />
</head>

<body>
<script>
$(function() {
$( "#dateDepart").datepicker();
});
</script>
Date:<input type="text" name="date" id="dateDepart" />
</body>
</html>

med@[Link] 347
Autocomplete
 L'autocomplétion est un widget qui était déjà présent dans
la version 1.6 de jQuery UI, mais qui avait été retiré dans la
version suivante, la 1.7.
 Pour la version 1.8, les développeurs de la librairie se sont
penchés dessus et l'ont amélioré, permettant ainsi de le
proposer de nouveau en libre téléchargement.
 Traditionnellement, ce plugin est utilisé dans les champs
de recherche, mais vous pouvez tout aussi bien
l'implémenter dans une suggestion de pseudonyme ou
de prénom, par exemple.
med@[Link] 348
Autocomplete
 Code HTML :
<div class="ui-widget">
<form>
Tags: <input type="text" id="recherche" />
</form>
</div>
 Code Java Script :
<script>
$(function() {
var liste= [
"ActionScript","AppleScript","Asp","BASIC","C",
"C++","Clojure","COBOL","ColdFusion","Erlang",
"Fortran","Groovy","Haskell","Java","JavaScript",
"Lisp","Perl","PHP","Python","Ruby","Scala","Scheme"
];
$( "#recherche"
).autocomplete({ source: liste
});
});
</script>
med@youssfi. 349
net
Autocomplete : Paramètres
 Spécification d'une longueur minimum
◦ Il existe une option qui permet d'exiger une longueur
minimum concernant la chaîne de caractère tapée par
l'utilisateur. En effet, par défaut, ce paramètre est
défini à 1.
$('#recherche').autocomplete({
source : [...],
/* on inscrit la liste de suggestions*/
minLength : 3
/* on indique qu'il faut taper au moins 3
caractères pour afficher l'autocomplétion*/
});

med@[Link] 350
Autocomplete : Paramètres
 Retour sur l'option « source »
◦ La liste des paramètres pouvant être
définis peut être allongée indéfiniment,
mais on utilisera, en général, la syntaxe
suivante :
 value, qui permet d'indiquer la valeur à inscrire dans le
champ de texte une fois sélectionnée ;
 label, qui désigne en fait le titre de la suggestion ;
 desc, qui donne la possibilité de spécifier une
description à chaque proposition ;
 icon, qui devra prendre une image pour valeur.
med@[Link] 351
Autocomplete : Paramètres
 Exemple :
$(function(){
var liste = [
{ value : 'Draggable', label : 'Draggable', desc :
'L\'interaction Draggable permet de déplacer un élément.' },
{ value : 'Droppable', label : 'Droppable', desc :
'L\'interaction Droppable permet de recevoir un élément.' },
{ value : 'Resizable', label : 'Resizable', desc :
'L\'interaction Resizable permet de redimensionner un
élément.' }
];
$('#recherche').autocomplete({
source : liste,
select : function(event, ui){
/* lors de la sélection d'une proposition */
$('#description').append( [Link] );
/* on ajoute la description de l'objet dans un bloc */
}
});
med@[Link] 352
Autocomplete : Paramètres
 l'option « position »
◦ Par défaut, la liste de suggestions se place en dessous
du champ de texte qui lui est associé.
◦ Il se peut que ça ne vous convienne pas, et comme le mot
d'ordre de la librairie est toujours « flexibilité », vous
pouvez définir une nouvelle position grâce à un
paramètre.
◦ Le paramètre position prend pour valeur un objet,
contenant les positions suivantes :
 my, qui définit la position de la liste autour du champ de texte ;
 at, qui définit la position de la liste dans le champ de texte ;
◦ Exemple :
$('#recherche').autocomplete({
source : [...],
position : {
my : 'bottom',
at : 'top'
} /* ici, ma liste se placera au-dessus et à l'extérieur de
champ de texte.*/ mon
});
med@[Link] 353
Barre de progression
 La barre de progression fonctionne grâce à un bloc div,
dans lequel s’implantera un deuxième bloc possédant
une largeur variable, qui fera donc office de progression.
 Bien sûr, cela fonctionne en interne, grâce à la librairie, ce
qui nous permet de n'avoir qu'un seul bloc à déclarer.
 Code JavaScript :
◦ $('#barre').progressbar();
 Le plugin possède un paramètre value, et permet
d'indiquer la valeur de progression, en pour cents (0-
100%).
◦ $('#barre').progressbar({
◦ value : 50 // remplit 50% (la moitié) de la barre
◦ });

med@[Link] 35
Boites de dialogue
<div id="dialog" title="Boîte de dialogue de base">
Cette boîte de dialogue peut être redimensionnée, déplacée et
fermée.
</div>

<script>
$(function() {
$( "#dialog" ).dialog({width:300,height:200});
</script>

Option zindex buttons


s
height et
width

modal

positio
n
l'accès à la page). La valeur par défaut est false.
Position de la boîte de dialogue sur la page (elle est centrée par
Hauteur et
largeur de la défaut). Z-index de la boîte de dialogue (1000 par défaut).
boîte de Un ou plusieurs boutons affichés dans la boîte de dialogue.
dialogue à med@[Link] 355
l'ouverture.

Initi
alis
éà
tru
e,
ren
d la
boît
e de
dial
ogu
e
mo
dal
e
(c'e
st-
à-
dire
inte
rdit
Boites de dialogue
<script>
$(function() {
$( "#dialog" ).dialog({
modal: true,
buttons: {
"Oui": function() {
$('body').css('background', 'yellow');
$( this ).dialog( "close" );
},
"Non": function() {
$( this ).dialog( "close" );
}
}
});
});
</script>
med@[Link] 356
Interactions:
• Selectable :
 JavaScript
<script>
$(function() {
$( "#selectable" ).selectable();
});
</script>

• Sortable:

 JavaScript
$(function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
});

med@[Link] 357
Interactions:
• Resizable :
 JavaScript :
$( "#resizable" ).resizable();

• Draggable :
 JavaScript :
$( "#draggable" ).draggable();

• Dropable :
 JavaScript :
$( "#dropable" ).dropable();

med@[Link] 358
Interaction : Sotable
 Code JavaScript :
<script>
$(function() {
$( "#sortable" ).sortable();
});
</script>

med@[Link] 359
Interaction : Dragable
 Code JavaScript :
<script>
$(function() {
$( "#draggable" ).draggable();
});
</script>

med@[Link] 360
Animation : Exemple
<div id="contenu">
<h3>Titre</h3>
<p>Contenu</p>
</div>
<script>
$(function() {
$('#contenu').show('explode');
$('#contenu').show('slide');
$('#contenu').show('fold');
});
</script>

med@[Link] 361
Animation des couleurs
 vouspourrez animer la couleur des éléments ! Les
propriétés sur lesquelles vous pouvez agir sont les
suivantes : backgroundColor
◦ borderBottomColor
◦ borderLeftColor
◦ borderRightColor
◦ borderTopColor
◦ color
◦ outlineColor
 La syntaxe de la méthode animate() ne change pas
:
$('sel').animate({ prop1: val1, prop2: val2 }, durée,
modèle, function() {
//Une ou plusieurs instructions
});

med@[Link] 362
Exemple d’animation des
couleurs
- Code HTML : - Code JavaScript :
<div id="contenu"> $(function() {
$('#contenu').toggle(
<h3>Titre</h3>
function() {
<p>Contenu Contenu Contenu
$('#contenu').animate({
Contenu Contenu Contenu</p>
backgroundColor: '#fff',
</div>
color: 'red',
- Code CSS : left: '+=200',
#contenu { width: 500
border: 4px gray solid; }, 1000 );
background-color: #aaeae1; },
color: black; width: function() {
100px; position: relative; $('#contenu').animate({
backgroundColor: '#aaeae1',
}
color: 'black',
#contenu h3{
left: '-=200',
margin: 0; padding:
width: 100
0.4em; text-align: }, 1000 );
center; background-color: }
#777; ); });
}
med@[Link] 363
AJAX
Principe de base HTTP

Client Serveur
Requête
HTTP HTTP Web SGBD
Moteur PHP
Java Réponse
Script [Link]
HTTP HTML

ou XML
Qu'est ce qu'AJAX ?

 Asynchronous JavaScript And XML.


 Ajax a exploité les technologies XML et java
script
 AJAX est un concept qui permet de faire
des appels asynchrones au serveur depuis
le client.
 Lors de ces appels, le serveur retournera
du XML qui sera "récupéré" par javascript
et traité.
 Nous verrons que nous pouvons tout aussi
bien faire transiter du texte et faire des
appels synchrones si l'on veut.
Problématique
 Avant toute chose, il serait bon de faire un
point sur le processus classique de
consultation d'un site ou d'une application
web :
◦ Vous saisissez une adresse dans votre navigateur.
◦ Cette "requête" finie par arriver sur le serveur web
qui héberge la page en question.
◦ Le serveur vous retourne du texte au format HTML
ou XHTML et éventuellement des images, feuilles de
style, fichiers JavaScript, applets java ....
◦ Votre navigateur les interprète et vous affiche la page.
◦ Vous êtes déconnecté du serveur web.
 Donc,quand vous cliquez sur un lien, vous
recommencez ce processus en entier avec
une nouvelle page.
◦ Dans le cas ou un formulaire se trouve sur la page,
vous envoyez les données sur le serveur qui vous
répondra après traitement de ces données.
Apport de ajax
 L'utilisation d'AJAX va
chambouler un peu cette
organisation car à tout moment
vous pouvez aller chercher des
informations sur le serveur pour :
◦Ajouter des éléments a la page
◦Modifier le contenu d'un "bout de la
page"
◦Insérer des données dans une base.
◦…
Utilisation de Ajax
 L'objet XmlHttpRequest
◦ AJAX se base sur l'utilisation d'un composant
embarqué dans presque tous les navigateurs
récents.
◦ Par contre, vous vous doutez bien que le
comportement va varier en fonction de ces
derniers.
◦ Pour pouvoir utiliser AJAX, il nous faut donc
créer en javascript un objet que l'on nomme
XmlHttpRequest ou xhr pour les intimes,
◦ comme son nom l'indique, cet objet nous
permet de faire des requêtes http pour
échanger du XML.
Création de l'objet XmlHttpRequest

var xhr = null;


if([Link]) // Firefox et
autres xhr = new XMLHttpRequest();
else if([Link]){ // Internet
Explorer try {
xhr = new ActiveXObject("[Link]");
}
catch (e) {
xhr = new ActiveXObject("[Link]");
}
}else {
// XMLHttpRequest non supporté par le navigateur
alert("Votre navigateur ne supporte pas les objets
XMLHTTPRequest...");
xhr = false;
}
Propriétés et méthode de l’objet xhr

 open("méthode","url",flag):
◦Ouvre la connexion avec le serveur.
 méthode -> "GET" ou "POST"
 url -> l'url à laquelle on va envoyer notre
requête.
 Si la méthode est GET, on met les paramètres dans
l'url.
 flag -> true si l'on veut un dialogue asynchrone,
sinon, false
Propriétés et méthode de l’objet xhr

 setRequestHeader("nom","valeur"):
◦ Assigne une valeur à un header HTTP qui sera
envoyé lors de la requête.
◦ Par exemple, pour un POST :
 nom -> "Content-Type"
 valeur -> "text/xml"
Propriétés et méthode de l’objet xhr
 send("params"):
◦ Envoi la requête au serveur.
◦ Si la méthode est GET, on met null en paramètre.
◦ Si la méthode est POST, on met les paramètres a
envoyer, sous la forme :
 "nomparam1=valeur1&nomparam2=valeur2".
 abort()
: Abandonne la requête.
 onreadystatechange :
◦ Ici, on va lui affecter notre fonction java script qui
sera exécutée à chaque "changement d'état" de
notre objet.
Propriétés et méthode de l’objet xhr

 readyState :
◦ C'est cette propriété qu'on va tester
dans le onreadystatechange.
◦ Elle représente l'état de l'objet et peut
prendre plusieurs valeurs :
 0 -> Non initialisé.
 1 -> Ouverture (open() vient de s'exécuter).
 2 -> Envoyé (send() vient de s'exécuter).
 3 -> En cours (des données sont en train d'arriver).
 4 -> Prêt (toutes les données sont chargées).
Propriétés et méthode de l’objet xhr

 status :
◦ Le code de la réponse du serveur.
 200 -> OK.
 404 -> Page non trouvée.
 ...
 statusText : Le message associé à status.
 responseText : La réponse
retournée par le serveur, au format
texte.
 responseXML: La réponse
retournée par le serveur, au format
dom XML.
Application AJAX PHP
 On souhaite créer une application web, utilisant ajax et JSP,
qui permet de présenter un catalogue de produits en ligne.
Chaque produit appartient à une catégorie.
 On considère une base de données MYSQL nommée «
Catalogue » qui contient deux tables :
◦ CATEGORIES (ID_CAT, NOM_CAT)
◦ PRODUITS (ID_PROD,NOM_PROD, PRIX, #ID_CAT)
 L’application que l’on souhaite créer doit permettre :
◦ Au chargement, afficher toutes les catégories dans une zone de liste
◦ En sélectionnant une catégorie, afficher les produits de cette
catégorie dans un tableau.
Première solution Ajax avec HTML

 Créer un script PHP qui permet de


générer une liste déroulante HTML qui
contient toutes les catégories
 Créer un script PHP qui permet de
générer un tableau HTML qui contient
les produits d’une catégorie donnée.
 Créer une page HTML avec le code
Ajax qui permet de :
◦ Au chargement afficher la liste des catégories
dans un div de la page
◦ En sélectionnant une catégorie, afficher les
produits de cette catégorie dans un autre
div.
Architecture

Client HTTP Serveur Web


1. Saisie URL: GET/[Link]
Moteur PHP
Cats: divC Rep HTTP : [Link]
[Link] Categories.
Produi

ts [Link]: php
GET/[Link]

divProds [Link]
Rep HTTP : Liste HTML
p
[Link]:
GET/[Link]?
idc=2 AddProduit.p
hp

Rep HTTP :Tableau


Produits
Catalogue.

htm
CATEGORIE

SGBD S PRODUITS

[Link]
[Link]
<html>
<head>
<script language="javascript" src="[Link]">
</script>
</head>
<body onload="chargerCategories()">
Catégories:
<div id="cats" style="display:inline"></div>
<hr/>
Produits
:
<div id="prods"></div>
</body>
</html>
[Link]
// JavaScript Document
function getXhr(){
var xhr = null;
if([Link]
t)
// Firefox et autres
xhr = new XMLHttpRequest();
else
if([Link]){
// Internet Explorer
try {
xhr = new ActiveXObject("[Link]");}
catch (e) { xhr = new ActiveXObject("[Link]");
}
} else {
// XMLHttpRequest non supporté par le navigateur
alert("Le navigateur ne supporte pas les objets
XMLHTTPRequest...");
xhr = false; }
return xhr;
}
[Link] (communication synchrone)

function chargerCategories()
{ var xhr=getXhr();
[Link]("POST","[Link]",false);
[Link]("");
var rep=[Link];
[Link]("cat").innerHTML=rep;
}
function chargerProduits(idc)
{ var xhr=getXhr();
[Link]("GET","[Link]?
cat="+idc,false); [Link](null);
var rep=[Link];
[Link]("prod").innerHTML=rep;
}
[Link] (communication asynchrone)
function chargerCategories(){
var xhr=getXhr();
[Link]("GET","[Link]",tru
e);
[Link]=function(){
if(([Link]==4)&&([Link]==200)){
var rep=[Link];
[Link]("cat").innerHTML=rep;
}
}
[Link](null);
}
function
chargerProduits(idc){ var
xhr=getXhr();
[Link]("GET","[Link]?cat="+idc,true);
[Link]=function(){
if(([Link]==4)&&([Link]==200)){
var rep=[Link];
[Link]("prod").innerHTML=rep;
}
}
[Link](null);
}
Ajax avec JQuery : [Link]
$(document).ready(function(){// Au chargement du document
chargerCategories(); // Faire appel à la fonction chargerCategories()
});
function chargerCategories(){
// Envoyer une requête Ajax avec la méthode GET au script [Link]
$.ajax({
url:'[Link]',type:'GET',dataType:'html',
success:function(reponse,status){ // En cas de succès
$("#cats").html(reponse); // Afficher la réponse dans le div cats
$("#cat").change(function(){chargerProduits($(this).val())});
/* En modifiant la valeur de la liste, faire appel à la fonction
chargerProduits(valeur de idCat sélectionnée) */
}
});
}
function chargerProduits(idc){
$.ajax({
url:'[Link]',type:'GET',dataType:'html',data:'cat='+i
dc, success:function(reponse,status){
$("#prods").html(reponse);
},
error:function(resultat,status,erreur){ // En cas d’erreur
$("#prods").html(erreur); // Afficher l’erreur
}
});
}
Ajax avec JQuery : les fonctions get() et post() de JQuery

$(document).ready(function(){
chargerCategories();
});
function chargerCategories(){
$.get('[Link]',function(reponse){
$("#cats").html(reponse);
$("#cat").change(function(){chargerProduits($
(this).val())});
}
);
}
function chargerProduits(idc){
$.get('[Link]','cat='+idc,function(reponse){
$("#prods").html(reponse);
}
);
}
JQuery et JSON
 Application : Consulter les produits par catégorie
[Link]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN"
"[Link]
[Link]">
<html xmlns="[Link]
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"
/>
<title>TP Ajax</title>
<script language="javascript" src="[Link]"></script>
<script language="javascript" src="[Link]"></script>
<script language="javascript"
src="[Link]"></script>
<link rel="stylesheet" type="text/css" href="[Link]" />
</head>
<body>
Catégries:<div id="cats" style="display:inline"></div>
<div id="prods"></div>
</body>
</html>
[Link]
$(document).ready(function(){
chargerCategories();
});
function chargerCategories(){
$.getJSON('[Link]',

function(data){ var res='<select


name="cat" id="cat"
onchange="chargerProduits([Link])">';
$.each(data, function(key,categorie){
res+='<option value="' +categorie['ID_CAT'] +'">'
+categorie['NOM_CAT']+'</option>';
}
);
res+="</select>";
$("#cats").html(res);
}
);
}
[Link]
function chargerProduits(idc){
$.getJSON('[Link]?cat='+idc,
function(data){ var res='<table border="1">';
res+='<tr><th>ID</th><th>NOM</th><th>PRIX</th>';
$.each(data, function(key,produit){
res+='<tr>';
res+='<td>'+produit['ID_PROD']
+'</td>';
res+='<td>'+produit['NOM_PROD']
+'</td>';
res+='<td>'+produit['PRIX']+'</td>'
; res+='</tr>';
}
);
res+="</table>";
$("#prods").html(res);
}
);
}
Une autre façon pour générer HTML avec JQuery
function chargerCategories(){
$.getJSON('[Link]', function(data){
$liste=$("<select>");
$[Link]("name","cat");
$[Link]("id","cat");
$[Link]("onchange","chargerProduits([Link])");
$.each(data, function(key,categorie){
$option=$("<option>");
$[Link]("value",categorie['ID_CAT']);
$[Link](categorie['NOM_CAT']);
$[Link]($option);
}
);
$("#cats").html($liste);
}
);
}
Une autre façon pour générer HTML avec JQuery
function chargerProduits(idc){
$.getJSON('[Link]?cat='+idc, function(data){
$tab=$('<table border="1">');
$[Link]($('<tr><th>ID</th><th>NOM</th><th>PRIX</th>
<th>ID
CAT</th></tr>')); for(i
in data){
$tr=$("<tr>");
for(attr in data[i])
{
$td=$("<td>").append(data[i][attr]);
$[Link]($td);
}
$[Link]($tr);
}
$("#prods").html($tab);
}
);
}
Client mobile Androïde
Voir Support : Application module [Link]

med@[Link]

Vous aimerez peut-être aussi