Upload
guillaume-beaulieu
View
112
Download
8
Embed Size (px)
Citation preview
Java EE
Java Enterprise Edition
Ce document a été contient des parties adaptées de support de cours de P.Y. Gibello, T. Dandelot et C. Dumoulin
•Le contenu de ce site est mis à disposition selon les termes de la
Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 France.
Introduction à JEEHistorique – Architecture - Offre
Historique Java
1.2 1.3 1.4.2 Java 5 Java 6 Java 70
500
1000
1500
2000
2500
3000
3500
4000
4500
nb classes JSE
http://docs.oracle.com/javaee/6/api/
http://docs.oracle.com/javase/6/docs/api/
J2EE 1.2.1
J2EE 1.3 J2EE 1.4 Java EE 5
Java EE 6
0
400
800
1200
1600
nb classes JEE
Java EE - Objectifs• Faciliter le développement de nouvelles
applications java à base de composants• Intégration avec les systèmes d’information
existants• Support pour les applications « critiques » de
l’entreprise– haute disponibilité, – tolérance aux pannes, – montée en charge, – sécurité – etc.
Architecture• Décompose le système à concevoir en
o applications, en composants applicatifs,o analyse descendante jusqu’aux modules, aux classes
gestionnaires, aux fonctions ou méthodes• Modules ou Objets gestionnaire, pour l’architecture logicielle
o Représente les fonctions du systèmeo Implémente les fonctions et sous-fonctions des cas d’utilisationo Services (ou fonctions) de gestion de données
• CRUD (Create, Read, Update, Delete) sur les données métier• Services de recherche sur les données métier
o services métiers• Transactions / Paiements• Calculs
5
Architectures informatiques
• Architectures pour une solution projet :o Architectures logiques
• applicative, • métier
o Architectures techniques• logicielle, • système, • réseau, • matérielle.
6
Architecture logique 4 tiers• IHM (ou GUI) : client
• Frontal (ou front-end) : présentation
• Dorsal (ou back-end) : métier
• Persistence : base de données
T1
T2
T3
T4
T2+T3
Mutualiser le code métier
T1
T2 Site Web
T3
T4
T2 Frontal API
T1+T2
Java EE – C’est quoi?• http://java.sun.com/javaee• Spécifications• Modèle de programmation• Implémentation de référence
• Standard en évolution depuis 1997– J2EE 1.0 à 1.4 en 2003, etc...
• Au départ, applications Web n-tiers– Présentation (Servlets puis JSP), essentiellement HTTP– Logique métier : EJB– Données : JDBC
• Puis infrastructure de support standard pour EAI– Facteurs de rationalisation majeurs (JTA, JMS, JCA, Web Services)– Evolution de progiciels existants vers Java EE
Architecture 4 tiers JEE
public static voidmain(…) {
ServletsJSPs
EJBs
WEB Container
EJB Container
Java EE Application Server
DB
EIS
Browser
Java Application
JDBC
JMS
JTA
JCA
JAAS
JavaMail
JNDI
…
java/flash
Applets
HTTP
SOAP, RESTRMI / IIOP
RMI / IIOPAppel local JVM
html
jdbc
xxxx
T1
T2
T1+T2
T1+T2
T3
T4
T4
Offre• Commerciale
• Oracle (ex BEA) WebLogic • IBM Websphere (n°1)
• Open Source• JBoss (n°1 en nombre de déploiements)• Oracle (ex Sun) Glassfish (« Platform edition »)• OW2 JOnAS• Apache Geronimo (« Community edition » de IBM Websphere)• openEjb
• Open Source conteneur web uniquement :• Tomcat• Jetty
Conteneur Webcouche de présentation
Servlet - WAR – JSP – taglib
Conteneur Web 1/2
webapp
Webapp
ServletServletServletServletServlet
htmlhtmlhtmljsp
jpg css
web.xml
htmljsjar
Conteneur Web 2/2• Contient des applications Web dans un
répertoire• Une application web est une arborescence
de fichiero mywebapp/WEB-INF/web.xmlo mywebapp/WEB-INF/classes/*.classo mywebapp/WEB-INF/lib/*.jaro mywebapp/**/*.*
• Un fichier « .war » est une archive zip de cette arborescence
Application Web• Servlets
• Code java exécuté sur le serveur pour retourner une page HTML
• Génération de contenu Web dynamique
• JSP: Java Server Pageso Mélange de HTML/XML et de code javao Librairies d ’extensions (« taglibs »)o Pré-compilation en servlet
Servlet• Programme java appelable depuis une URL• Classe qui hérite de
javax.servlet.http.HttpServlet • Cycle de vie de HttpServlet
o init() : 1er appel o service() : chaque appel, redirection vers doGet() ou
doPost()o destroy() : arrêt du serveur WEB
• Appel d’une servlet• URL GET : http://myserver/mywapp/HelloWorld : doGet()• <form method="post" target="…"> : doPost(),
Exemple de servletimport java.io.*; import javax.servlet.*; import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>");out.println("<h1>hello word !</h1>");out.println("</body></html>");
}}
Ecrire une Servlet• Classe qui hérite de la javax.servlet.Servlet• Surcharger la méthode d ’initialisation init(),
o Utiliser la méthode getInitParameter()• Surcharger une méthode de gestion d’appel
o doPost(), doGet(), doPut(), doDelete(), doOptions()
• Analyser la requête, o Classe HttpServletRequest
• getParameter(), getCookie(), getSession()• Utiliser la classe HttpServletResponse pour
répondre• getWriter(), setContentType(), setCookie()
formulaire et Servlet• Champs des formulaires directement dans des variables :
<FORM ACTION="testServlet" METHOD="POST"> Votre nom : <INPUT TYPE=TEXT NAME="nom"> Votre âge : <INPUT TYPE=TEXT NAME="age"> <INPUT TYPE=SUBMIT VALUE="Ok"></FORM>
• Dans TestServlet.doGet(), l’objet request contient les saisies:
o request.getParameter("nom")o request.getParameter("age")
public void doGet( HttpServletRequest request, HttpServletResponse response) ... {
…out.println("Bonjour " + request.getParameter("nom"));… 19
Déployer une servlet• Recopier l’application web sous
$tomcat/webappso une archive .warouo Un répertoire
• Contenu de l’application webo sous-répertoire « WEB-INF/ »
• web.xml : déclaration et paramètres de servlets• /lib/ : pour les .jar, • /classes/ pour les .class
Déclaration de la servlet
<web-app><servlet>
<servlet-name>servletHello</servlet-name> <servlet-class>HelloWorld</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>servletHello</servlet-name> <url-pattern>/hello</url-pattern>
</servlet-mapping> </web-app>
http://localhost:8080/myapp/hello
apache-tomcat-7.0.30/webapps/myapp/WEB-INF/web.xml
Autour des Servlets• Gestion de la session : HttpServletRequest.getSession()
o données de contexte à durée de vie courteo stockées sur le serveuro addAttribute(), getAttribute(),
setMaxInactiveInterval()• Gestion des cookies : HttpServletRequest.getCookies()
o données de contexte à durée de vie plus longueo stockées sur le poste cliento setName(), setValue(), setMaxAge()
• Filtre o Transforme des requêtes et/ou des réponseso Classe qui implémente javax.servlet .Filtero Déclaré dans web.xml comme une Servlet
JSP• Java Server Pages• Intégration de code serveur dans un fichier
HTMLomêmes principes que PHPoCode java dans des balises <%...%>o Les pages JSP ont l’extension « .jsp »
• L’interpréteur JSP génère une classe de servlet « .java » par JSPo des variables accessibles dans des pages
(session, application, request, response)
23
Exemple de JSP<%@page import="java.util.*" %> <HTML> <HEAD> <TITLE>Test HelloWorl en JSP</TITLE></HEAD> <BODY><% out.println("Hello world !"); out.println("Hello " + request.getParameter("name"); %> <p>Today is <%= new Date() %></BODY></HTML>
24
Directive
Scriptlet
Expression
interprétation script
25
Hello worldToday number is 19
<HTML> <BODY> Hello world !<script type="text/javascript"><!– var now = new Date();document.write("today is " + now.getDay());//--> </script></BODY></HTML>
<HTML> <BODY> <%="Hello world !"%><script type="text/javascript"><!– var now = new Date();document.write("today is " + now.getDay());//--> </script></BODY></HTML>
Coté serveur
Coté client
Vue utilisateur
interprétation client
interprétation serveur
variables prédéfinies JSP• out : flux de sortie dans la réponse HTTP au client.
o utiliser println()
• request : objet représentant la requête HTTPo utiliser getParameter("name"), getCookies(), forward()
• response : objet représentant la réponse HTTPo out est retournée par response.getWriter()o utiliser setCookie(new Cookie("name","value"))
• session : objet représentant la session HTTPo utiliser setAttribute("name"), getAttribute("name"), removeAttribute("name")o La session de l’utilisateur est retourner par request.getSession(false)o request.getSession(true) crée et retourne une nouvelle session (déconnexion ou
logout)
• pageContext : objet représentant le contexte d'une page• Facilite l'accès au contexte de l'application web• utiliser setAttribute("name") pour donner des paramètres aux taglibs• Utiliser foward("url") pour déléguer la réponse à une autre page
formulaire et JSP• Champs des formulaires directement dans des variables :
<FORM ACTION="test.jsp" METHOD="POST"> Votre nom : <INPUT TYPE=TEXT NAME="nom"> Votre âge : <INPUT TYPE=TEXT NAME="age"> <INPUT TYPE=SUBMIT VALUE="Ok"></FORM>
• Dans test.jsp, l’objet request contient les saisies:
<%request.getParameter("nom")request.getParameter("age")%>
• On peut écrire en réponse dans test.jsp:...Bonjour <% out.println(request.getParameter("nom")); %>...
27
syntaxe JSP• <% … %> : scriptlet• <%! … > : déclaration servlet <%! int myVariable = 0; %>
• <%-- Voici un commentaire JSP --%>• <%= … %> : expression (pas de ; final)• <%@... %> : directive <%@page import="…", <%@include page="url"
• <jsp:…> : tag jsp <jsp:include>, <jsp:forward>• TagLib JSTL <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"
%>
• Autres TagLib : Struts2, Tiles, Spring MVC, etc.
Librairie URI Préfixe
core http://java.sun.com/jsp/jstl/core c
Format http://java.sun.com/jsp/jstl/fmt fmt
XML http://java.sun.com/jsp/jstl/xml x
SQL http://java.sun.com/jsp/jstl/sql sql
Fonctions
http://java.sun.com/jsp/jstl/functions fn
Forward vs redirect• Forward utilisable
dans un même war• Redirect sinon
Page A Page B Page C
forward
redirect
this.getServletConfig().getServletContext().getRequestDispatcher( "/JSP/Demo.hello.jsp").forward(request,response);
<jsp:forward page="/jsp/welcome.jsp"/>
Forward pour les erreurs
Page1.jsp
Nb pizza incorrect…<% if (nbPizza<=0) { %><jsp:forward page="Page1.jsp"><jsp:param name=”errMsg" value=”Nb pizza incorrect" /> </jsp:forward> <% } %>
Page 2.jsp
-2
Utilisation des taglibs 1/2
• Rajout des jars correspondant dans WEB-INF/libo WEB-INF/lib/jstl.jaro WEB-INF/lib/standard.jar
• Exemple :
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html><body><% pageContext.setAttribute("now",new java.util.Date()); %>"…<fmt:formatDate pattern="yyyy-MM-dd" value="${now}" />…</body></html>
Utilisation des taglibs 1/2… code HTML …
<jsp:useBean id=“user” class=“com.acme.EndUser” scope=“session” />
… code HTML …
<? user.setName(“Dupont”); ?>
<h2>Welcome, <c:out value="${user.name}”/>
<? EndUser user = new EndUser(); user.setName(“Dupont”); ?><h2>Welcome, ${user.name}”
Ou
Conteneur Webcouche de persistance
JDBC – Transaction
Architecture webapp
Java DataBase Connectivity
• Librairie d’interfaces java qui définisse la communication avec une base de données
• Package « java.sql »o classe « DriverManager », interface « Driver »
• démarrage d’une connexiono interfaces « Connection », « DatabaseMetaData »
• Gestion d’une connexion et création de requêtes SQLo interface « Statement » et spécialisations
• gestion, exécution d’une requête SQLo interfaces « ResultSet », « ResultsetMetaData »
• gestion des résultats de requête SQL
Application Java
JDBC DriverManage
r
MySQL JDBC Driver
MySQL Oracle
Oracle JDBC Driver
Connexion via JDBC• Classe DriverManager
o DriverManager.getConnection(url,user,password)
• Interface « java.sql.Connection »o Gère la connection à la base
• close(), getMetaData()o Création d'une nouvelle requête
• Statement stmt = createStatement();• prepareStatement("select a from b where c=?")
o pour optimisation, ‘ ? ’ = paramètre, ordre important• prepareCall("? = call proc_stock[?,?]")
o procédure stockée (attention à la portabilité !)o Gestion du transactionnel
• commit(), rollback(), setAutoCommit(boolean)
Temps d'exécution
long
À considérer
comme monothrea
d
Exemple de connexion/** retourne une connection à une base de données accessible via JDBC * @param dbURL - URL de la base de données * @param driverClassName - nom complet de la classe qui sert de driver JDBC * @param user - nom de compte utilisateur de la base de données * @param password - mot de passe associé au compte utilisateur */public Connection connect(String dbURL, String driverClassName, String user, String password)
throws Exception {
// configure le DriverManager pour charger le driver try { Object drv = Class.forName(driverClassName).newInstance(); } catch( Exception e) { e.printStackTrace(); throw e; }
Connextion connection = null; try { connection = DriverManager.getConnection(dbURL, user, password); return connection; } catch( SQLException se) { se.printStackTrace(); throw se; }
}
Exemple de update• Connection cnx =
DriverManager.getConnection("jdbc:mysql://localhost:3306/pizzadb","com.mysql.jdbc.Driver","user","****");
• PreparedStatement updateVentes = cnx.preparedStatement("UPDATE CAFE SET VENTE = ? WHERE NOM_CAFE LIKE ?");updateVentes.setInt(1,50);updateVentes.setString(2, "Colombian");updateVentes.executeUpdate();
• Statement stt = cnx.createStatement();stt.executeQuery("UPDATE CAFE SET VENTE = 50 WHERE NOM_CAFE LIKE 'Colombian' ");
Requêtes via JDBC• « Statement » représente une requête
o Exécution d’une requête SQL• Resulset res = statement.executeQuery("select …");• int nbRows = statement.executeUpdate("update …");
o Pagination des résultats• setMaxRows(n), getMoreResults()
o contrôle de l’exécution de la requête• setQueryTimeout(int seconds), cancel()
• PreparedStatement, CallableStatemento set<Type>(n°param,valeur) avec pour <Type> :
• String, Long, Double, BigDecimal, Boolean, Date, etc.
Résultats via JDBC• « Resultset » représente le résultat d’une requête
o méthodes principales :• get<Type>(nom_colonne)• next()
o exemple: while(rst.next()) { … gestion d ’une ligne … }• getMetaData()
• « ResultsetMetaData » décrit le résultat (= la table si « select * »)o getColumnCount(), getColumnType()
isNullable(), getColumnLabel(), etc.
Exemple de insertPizza p = new Pizza("royale","tomato");Statement stt = cnx.createStatement();int nbLigneCrees = stt.executeUpdate("INSERT INTO pizza (pizza_name,pizza_type) VALUES ('"+p.getPizzaName()+"','"+p.getPizzaType()+"')", Statement.RETURN_GENERATED_KEYS);ResultSet generatedKeys = stt.getGeneratedKeys();if (generatedKeys.next()) { p.setId(generatedKeys.getLong(1)); }
ALTER TABLE pizza CHANGE pizza_id pizza_id BIGINT( 20 ) NOT NULL AUTO_INCREMENT
MySQL
Exemple de select// affiche les noms des cplonnes puis chaque ligne de résultat de la requêteStatement stmt = connection.createStatement();ResultSet rst = stmt.executeQuery("select c.chatRoomName, t.topicName, c.language,
from ChatRoom c, TopicCategory twhere c.topicCategoryId = c.Idorder by topicName, chatRoomName");
ResultSetMetaData rstData = rst.getMetaData();Collection<ChatRoom> chatRooms = new Vector<ChatRoom>();while(rst.next() == true){
ChatRoom chatRoom = new ChatRoom();chatRoom.setRoomName(rst.getString("chatRoomName"));...chatRooms.add(chatRoom);
}
// fermeture de la requête et de ses Resultset associésstmt.close();
43
Transactions sous MySQL
• Transactions en SQLo BEGIN, COMMIT, ROLLBACK, CHECKPOINTo option AUTOCOMMITo Note : les DDL (create, alter, drop table) sont toujours
AUTOCOMMIT
• Accès concurrents : ligne ou table bloquée jusqu’au commit ou rollbacko LOCK TABLE o SELECT … FOR UPDATEo Gestion optimistes des accès concurrents
• Moteurs pour la base MySQLo InnoDB : foreign keys, select for update, stockage optimiséo MyISAM : plus rapide en lectureo MEMORY : pas de stockage sur le disqueo NDBCluster : table répartie sur plusieurs serveurs
44
Illustration d’une transaction
• Table possessions (d’actions par utilisateurs)
• Table comptes
• Scénario 1 : l’utilisateur A achète 200 actions Axa à l’utilisateur B pour 37 euros
id solde utilisateur
1 3200 A
2 1540 B
3 2030 C
id action
quantite
cote utilisateur
version
1 Total 200 149,90
C 2
2 Axa 500 36,50 B 1
3 EDF 150 82,20 A 4
45
gestion optimiste des accès concurrents
• Scénario 1
• Scénario 2 : l’utilisateur C achète aussi 400 actions Axa à l’utilisateur B pendant le scénario 1
id action
quantite
cote utilisateur
version
1 Total 200 149,90
C 2
2 Axa 500 36,50 B 1
3 EDF 150 82,20 A 4
id solde utilisateur
1 1350 A
2 3390 B
3 2030 C
id action
quantite
cote utilisateur
version
1 Total 200 149,90
C 2
2 Axa 300 36,50 B 2
3 EDF 150 82,20 A 4
4 Axa 200 36,50 A 1
Exemple de transaction JDBC
• cnx.setAutoCommit(false);PreparedStatement updateVentes = cnx.prepareStatement("UPDATE CAFE SET VENTE = ? WHERE NOM_CAFE LIKE ?");updateVentes.setInt(1,50);updateVentes.setString(2, "Colombian");updateVentes.executeUpdate();PreparedStatement updateTotal = cnx.prepareStatement("UPDATE CAFE SET TOTAL = TOTAL + ? WHERE" + "NOM_CAFE LIKE ?");updateTotal.setInt(1,50);updateTotal.setString(2,"Colombian");updateTotal.executeUpdate();cnx.commit();
Cet exemple ne gère pas les accès concurrents
Log4jIntroduction au système de trace coté serveur
Log4j• Librairie de génération de traces dans un fichier• Utiliser des fichiers de log au lieu de System.out• Types de traces : ERROR, INFO, DEBUG• Installation : log4j-<version>.jar dans le
CLASSPATH• Logger : générateur de la trace• Appender : destination de la trace• LayoutPattern : format de la trace• Configuration
o Log4j.propertieso Log4j.xml
Exemple de config. log4j
• <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
• <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
• <layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%d %t %c{2} - %m%n"/>
• </layout></appender>• <category name="fr.isen">• <priority value="DEBUG"/>• </category>• <root>• <priority value="ERROR"/>• <appender-ref ref="ConsoleAppender"/>• </root></log4j:configuration>
Exemple de code log4j• public class DAOBase {• ...• final static Logger logger =
Logger.getLogger(DAOBase.class);• ...• public void aMethod() {• ...• connection = DriverManager.getConnection(dbURL,
user, pwd);• if(logger.isDebugEnabled()) {• logger.debug("connected to " + dbURL);• }• ....
JunitIntroduction aux tests unitaires et à l'intégration continue
JUnit• Cadriciel de création de tests unitaires• Génération de tests unitaire possible depuis
Eclipse• Un test unitaire teste une méthode ou une
fonctiono différent des tests fonctionnels qui testent les fonctions de
l’application,
• Lancement possible depuis Eclipse
• Code à isoler en gestionde configurationo sous « src/test »
Exemple de junitimport static org.junit.Assert.*;import org.junit.Test; public class StringTest { @Test public void testConcatenation() { String foo = "abc"; String bar = "def"; assertEquals("abcdef", foo + bar); } @Test public void testStartsWith() { String foo = "abc"; assertTrue(foo.startsWith("ab")); } }
@Test(expected = NullPointerException.class)public void methodCallToNullObject() { Object o = null; o.toString();}
Connection cnx = null@Beforepublic void setUp() throws Exception {
cnx = new DAOBase().getConnection(
dbUrl,dbDriver, dbUser, dbPassword);}
Méthode d’assertionMéthode Rôle
assertEqualsVérifie que deux objets sont égaux, avec la méthode equals()
assertFalse Vérifie que l'expression est fausse
assertNotNull
Vérifie que l'objet n'est pas nul
assertNotSame
Vérifie que deux références ne sont pas les mêmes
assertNull Vérifie qu'un objet est nul
assertSameVérifie que deux références sont les mêmes, avec l’opérateur ==
assertTrue Vérifie que l'expression est vrai
fail Provoque l'échec du test
Junit depuis Eclipse
Création :• bouton droit sur une classe,
puis New, Other, Java, Junit, TestCase
• Génerer le code de test sous un autre répertoire « /test »
Utilisation :• bouton droit sur une Junit
puis Run As, Junit Test
Tests unitaires• Un test unitaire teste une méthode ou une fonction
o différent des tests fonctionnels qui testent les fonctions de l’application,
• Tests unitaires automatisés o lancés après la construction d’un exécutableo Utilisés pour l’intégration continue
• Tests unitaires d’intégrationo lancés après l’installation d’une applicationo Fonctionnement interneo Fonctionnement de l’IHM
DéploiementTests unitaires Documentation Contrôle qualitéCompilation
Vérification de l’état du référentiel
Compilation
Génération dedocumentation
Récupérationdes sources
Exécution destests unitaires
Packaginget déploiement
Calcul demétriquesqualité
Livraiso
n de code
Déploiement
Consultation des métriques qualité
Tests
Notifications
Développeurs
Testeurs
1
5
6
7
3
En cas de modifications, l’usine logicielle procède à la construction du projet
En cas de modifications, l’usine logicielle procède à la construction du projet
2
A intervalle régulier l’état du référentiel de sources est vérifié
A intervalle régulier l’état du référentiel de sources est vérifié
4
En cas d’échec, la résolution du problème devient la priorité de l'équipe
En cas d’échec, la résolution du problème devient la priorité de l'équipe
Les développeurs livrent leurs modifications en continu
Les développeurs livrent leurs modifications en continu
Usine logicielle
Référentieldes sources
SCM
Environnement de développement,d’intégration ou de recette
Processus de l’intégration continue
Log4J - JUnit
JNDIIntroduction à l'informatique distribué et à RMI
Objets distribué
• Prinpices :o Faire coopérer des logiciels entre euxo Avoir des "variables globales" au réseauo Utiliser et répartir la puissance de calcul et de
stockages sur plusieurs serveurso Appeler une méthode d'un objet se trouvant sur une autre
machine exactement de la même manière que s’il se trouvait au sein de la même machine
o Pouvoir retrouver un objet existant d'après son « nom »
Middleware
ObjetStub
Client Serveur
ObjetServant
60
Machine 2Machine 1Machine 1
Comment sont vu les objets.
Application Application
Objet Stub
Imp
lem
en
tatio
n
Sq
uele
ton
Mode classique Mode distribué
Interface
Utilisation de l'annuaire
ServeurClient
Annuaire
1- Déclare un objet 2- Recherche un objet
Object o = envCtx.lookup("MyObj");
3 - Appel l'objet
TechnologiesObjets distribués
Technologie Responsable
RPC IETF C, C++
CORBA OMG tous
RMI Oracle (ex Sun) java
SOAP (WebService) W3C tous
WCF Microsoft .Net
HTTP+REST+XML/JSON
?, pas de norme tous
63
Java RMI• Remote Method Incocation• Permet à du code client d'appeler une méthode
sur un objet serveur Java distant.• simplification de CORBA pour java uniquement.• Générateur de code Stub et Skeleton à partir
d'une interface : rmic• Annuaire d'objet serveur disponible rmiregistry• Package java.rmi• Disponible dans Java SE
JNDI• Java Naming and Directory Interface• Service de nommage / annuaire pour JEE• API accès aux annuaires
– javax.naming– « Service Provider » par annuaire cible (LDAP, NIS, RMI registry…)
• Utiliser dans JEE pour accéder à des • DataSources• UserTransaction• EJB• Etc.
• JEE est une évolution de CORBA pour Java
Déclarer une DataSourcedans Tomcat
• $tomcat/webapps/myapp/META-INF/context.xmlo <Resource name="jdbc/PizzaDB"o auth="Container"o type="javax.sql.DataSource"o username="root"o password="root"o driverClassName="com.mysql.jdbc.Driver"o url="jdbc:mysql://localhost:3306/pizzadb"o maxActive="8"o maxIdle="4"/>
• $tomcat/webapps/myapp/WEB-INF/web.xmlo <resource-ref>o <res-ref-name>o jdbc/PizzaDBo </res-ref-name>o <res-type>o javax.sql.DataSourceo </res-type>o <res-auth>o Containero </res-auth>o </resource-ref>
Création d’une
DataSource dans Tomcat
Utilisation d’une
DataSource
Context initCtx = new InitialContext();Context envCtx = (Context) initCtx.lookup("java:comp/env");DataSource ds = (DataSource) envCtx.lookup("jdbc/PizzaDB");
Construction de livrables
Ant - Maven
Ant• http://ant.apache.org• Outil pour construire un livrable jar, war, ear• Remplace les fichiers "make"• Intégrer à Eclipse (démarrage, configuration)• Doc. sous $ANT_HOME/docs/manual/index.html et http://ant.apache.org/manual/tasksoverview.html
• Suite sur le support de cours Ant de T. Dandelot
EJBEJB Session – JPA – JMS/MDB
EJB• Enterprise Java Beans• Cadriciel de logique métier coté serveur• S’appuie sur Java SE et les APIs de Java EE
– JNDI, JTA/JTS, JDBC, JMS, JAAS• Gestion déclarative :
• personnalisation par annotations (@... dans le code)ou • descripteur de déploiement (xml)
• "Portable" sur les différents conteneurs EJB
Architecture 4 tiers JEE
public static voidmain(…) {
ServletsJSPs
EJBs
WEB Container
EJB Container
Java EE Application Server
DB
EIS
Browser
Java Application
JDBC
JMS
JTA
JCA
JAAS
JavaMail
JNDI
…
java/flash
Applets
HTTP
SOAP, RESTRMI / IIOP
RMI / IIOPAppel local JVM
html
jdbc
xxxx
T1
T2
T1+T2
T1+T2
T3
T4
T4
Services du conteneur d'EJB
• Annuaire de composants EJB et de ressources
• Grappe de ressource (pool)• Transactions• Persistance• Répartition de charge• Sécurité
interface d'un EJB• Déclare l'annotation @Remote
• Déclare les méthodes métier
• C'est une vue cliente et distante de l’EJB
• Paramètres passés par copie• Retour et exceptions également
import javax.ejb.Remote;...@Remotepublic interface PizzaManager { public Long orderPizza(PizzaOrder po, EndUser eu); ...
Doiventimplémente
rSerializable
Implémentation d'un EJB• Implémente les méthodes de l’interface
Remote• Peut hériter d’un autre EJB, ou d’un POJO• Spécifie les caractéristiques de déploiement
par annotations– type d'EJB (Stateless, Stateful, Message)– transactions,– sécurité,– persistance– webservice
Exemple de code@Stateless(mappedName="PizzaManager")Public class PizzaManagerBean implements PizzaManager { public Long orderPizza(PizzaOrder po, EndUser eu) { ...
Serveur
Context ctx = new InitialContext();PizzaManager pm = (PizzaManager)ctx.lookup("java:global/PizzaEAR/PizzaFrontOffice/PizzaManagerBean");...pm.creatPizzaOrder(po);
Client distant
@EJB(name="PizzaManager")private PizzaManager pizzaMgr; // Injection d’EJB local
Client local
EJB Session• Réalisation d’actions sur demande de
clients
• Objets métier gestionnaire non persistants• Ce n'est pas une entité métier sauver en base de
données
• Session Stateless ou Stateful
• Un Bean Stateful gère un l’état• il est plus difficile de le dupliquer
Caractéristiques de déploiement
• Stateless Session Bean • Grappe d’instances possible• Appels de méthodes " idempotent "
• Stateful session / Activation / Passivation• @PostActivate après activation• @PrePassivate avant passivation
• Pour tous les Session Beans• Callbacks @PostConstruct et @PreDestroy• @TransactionManagement(value=TransactionManagementType.BEAN
)• @RolesAllowed("front-office","back-office"} )
EJB : Configuration & Déploiement
• Descripteur de déploiement : • META-INF/ejb-jar.xml
<enterprise-beans>– Description du Bean (Stateful, Stateless, ...)– Ressources (Base de données,...)– Securité: permissions et rôles– Transactionnels
</enterprise-beans>
• Priorité au descripteur de déploiement sur les annotations.
Descripteur de déploiement (optionnel)
<enterprise-beans> <session> <description>EJB PizzaShop</description> <ejb-name>PizzaManager</ejb-name> <business-remote>...PizzaManagerRemote</business-remote> <ejb-class>...PizzaManagerBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Bean</transaction-type> <resource-ref> <res-ref-name>jdbc/facturationDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </session></enterprise-beans>
Lien entreinterfaces etimplémentation
Ressource :ici, base de données
Bean Session
Beanou Container
Injection de dépendances
• Variable d’instance initialisée par le conteneur– Alternative au lookup JNDI– Interne à une application JEE serveur uniquement
• Dans un client d'EJB (par exemple une Servlet)• @EJB(mappedName="java:global/PizzaEAR/PizzaFrontOffice/
PizzaManagerBean")private PizzaManager pizzaMgr; // Injection d’EJB local
• Dans l'EJB• @Resource(name="java:/PizzaDS")
javax.sql.DataSource ds; // Injection de ressource via nom JNDI
Gestion des erreurs• Exception métier
o L'utilisateur est la cause de l'erreur ou peu la résoudreo Le développeur doit créer des exception métier qui :o héritent de java.lang.RuntimeExceptiono Utilisent l'annotation
@ApplicationException(rollback=true)
• Exception techniqueo Réutiliser les exceptions disponibles
• ServletException, dans les servlets et JSP• EJBException dans les EJB• SQLException dans les DAO
@ApplicationException(rollback=true)public class BusinessException extends RuntimeException {....
Packaging EAREAR JARJARJAR
EJB-JAR WAREJB-JAR
/lib
<application><display-name>PizzaEAR</display-name> <module><ejb>PizzaEJB.jar</ejb></module> <module> <web> <web-uri>PizzaFrontOffice.war</web-uri> <context-root>Pizza</context-root> </web> </module></application>
/META-INF/application.xmlhttp://localhost:8080/Pizza/
Rappel sur le chargement de
classes• Les classloaders sont hiérarchisés
• Règle : 1. Cherche la classe dans le cache de son niveau 2. Demande la classe au classloader parent3. Si ClassNotFoundError pour le parent alors cherche
la classe à son niveau4. Si toujours pas trouvé alors ClassNotFoundError
• Hierarchie standard (hors JEE), du pères aux fils
o Bootstrap : java.*o Extension : $JRE_HOME/ext/*.jaro System (ou application si non JEE) : $CLASSPATH
Gestion du classpath JEE
Module Classpath
EAR 1. All JARs in the /lib directory of the EAR2. Manifest Class-Path of any JARs in 1
EJB-JAR 1. EJB-JAR file itself2. JARs referenced by manifest Class-Path of EJB-JAR3. JARs referenced by manifest Class-Path of above
JARs (in 2)
WAR 1. WEB-INF/classes2. JARs in WEB-INF/lib3. JARs referenced by manifest Class-Path of WAR4. JARs referenced by manifest Class-Path of JARs in 2
and 3
Class-Path: lib/PizzaBiz.jar PizzaEjb.jar lib/log4-j1.2.16.jar lib/jackson-databind-2.0.6.jar lib/jackson-core-2.0.6.jar
Exemple : META-INF/MANIFEST.MF de Pizza.war dans Pizza.ear
Retour à la ligne
obligatoire !
Répartition de charge : notations
web
ejbweb
web ejb
Apache mod_jk
ejbUn conteneur Web Un conteneur EJB
Un serveur qui hébergeun conteneur Web
Un serveur qui hébergeun conteneur EJB
Un serveur Apache avec le module mod_jk
Un noeud (machine) qui héberge un ou plusieurs serveurs
Un serveur qui héberge un conteneur Web et un conteneur EJB
Répartition de charge : scenarii (1)
ejbweb web ejb
Compact Réparti(au sein d ’un même nœud)
web ejb
Réparti
Répartition du serveur JavaEE
Répartition de charge : scenarii (2)
Apache mod_jk
ejbweb
ejbweb
(1)
Apache mod_jk
Apache mod_jk
web
ejb
web
(3)
Apache mod_jk
web ejb
web ejb
(4)
Répartition de charge EJB
Réplication session http
web ejb
web ejb
(2)
Répartition de charge depuis un load
balancer
Gestion des transactions
• Utilisation de JTA o javax.transaction.UserTransactiono Contrôle de la transaction (timeout,
« rollbackOnly »)
o Exemple :
UserTransaction utx = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
utx.begin();…utx.commit();
Gestion déclarative des transactions
• Au niveau de la méthode de l'EJB
• Required (valeur par défaut)– Si pas de transaction, nouvelle transaction
• Supports– Si transaction courante, l’utiliser
• NotSupported– Si transaction courante, elle est suspendue
• RequiresNew– Nouvelle transaction (s'il y a un transaction courante, elle est suspendue)
• Mandatory– Exception si pas de transaction courante
• Never– Exception si transaction courante
@TransactionManagement(javax.ejb.TransactionManagementType.CONTAINER)public class Facturation implements FacturationRemote {
@TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)public void creerFacture( ) {
// …}
Gestion déclarative des Transactions par
annotations
NotSupportedRequiredRequiresNewMandatorySupportsNever
Descripteur de déploiement :
Gestion déclarative des Transactions par xml
<assembly-descriptor> <container-transaction> <method> <ejb-name>Facturation</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction>
...</assembly-descriptor>
NotSupportedRequiredRequiresNewMandatorySupportsNever
Persistance + TransactionsEJB1
DB
M
RE
G
JMX
EJB
EJB2
DB
M
EJB
JMX
JTM
JMX
Web
ConteneurEJB
ConteneurEJB
ConteneurWEB
DD
2-phasecommit
T1
T2
DB1
DB2
Appli client
http
server3
server2
server1
no cust
Servlet
JPA• Java Persistence API
• Un diagramme de classes métier correspond àun modèle de base de donnée relationnel
• Annotations de correspondance objet-relationnelo Déclaration des tables et colonnes correspondanteso Déclaration des associationso Déclaration de l'héritage
• Utilisation de JPA dans le code java• Framework : Hibernate, EclipseLink, ObjectDB,
OpenJPA• Alternatives : JDO, JDBC
94
Annotations JPA• Annotations à insérer dans les classes métier
pour définir le mapping objet relationel• Annotations JPA
o Classe métier : • @Entity • @Table(name="<nom_table>")• @MappedSuperClass : pour les classes mère abstraites
o Attributs dans classe métier :• @Column(name="<nom_colonne>", length=<taille>,
nullable=<true|false>)• @Id : la colonne est l’identifiant unique de la table• @GeneratedValue : valeur non fournie par le
développeur• @Version : colonne technique utilisée pour la gestion
optimiste d’accès concurrents• @Transient : ignoré par JPA (non sauvé)
@Entity@Table(name="pizzaorder")public class PizzaOrder implements Serializable { // Serializable conseillépublic PizzaOrder () { } // Constructeur par défaut obligatoire
@Id@GeneratedValue(strategy=GenerationType.IDENTITY)public Long id;
@Column(name="order_date")private Date orderDate;
@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.REFRESH)@JoinColumn(name="enduser_id")protected EndUser customer;___________________________________@Entity@Table(name="enduser")public class EndUser implements Serializable {...@OneToMany(mappedBy="customer", cascade=CascadeType.ALL, fetch=FetchType.LAZY)private Collection<PizzaOrder> pizzaOrders;
Exemple 1/2
Associations(1 EndUser , N
PizzaOrder)
Nom de colonne différent
Pour MySQL Autoincreme
nt
Associations• Exemple : EndUser OneToMany PizzaOrder
• Le « propriétaire » de la relation correspond à la table qui possède la clé étrangère
– Lien EndUser/PizzaOrder : PizzaOrder est « propriétaire » de la relation
– Attribut « mappedBy » côté EndUser, et joinColumn côté PizzaOrder
• OneToOne– Exemple : EndUser et Address
• OneToMany– Exemple : EndUser vers PizzaOrder
• ManyToOne– Exemple : PizzaOrder vers EndUser
• ManyToMany– Exemple : Pizza et PizzaOrder
97
Jointures en JPA@ManyToOne(fetch=FetchType.LAZY)@JoinColumn(name="<nom_colonne>", unique=true, nullable=true)
@OneToMany(mappedBy="<nomAttributClasseAssociée>", cascade=CascadeType.ALL)
@ManyToMany@JoinTable(name="<nom_table>",
joinColumns = @JoinColumn(name ="<nom_colonne>"), inverseJoinColumns = @JoinColumn(name ="<nom_colonne>" )
OneToOne : idem ManyToOne d'un coté et OneToMany de l'autre
CascadeType : ALL, MERGE, PERSIST, REFRESH, REMOVE, DETACHFetchType : LAZY, EAGER
CascadeCascadeType
Effet
ALL Tous les effets ci-dessous, valeur par défaut
PERSIST Si l'entité à créer possède des entités dans l'association concernée,alors elles sont créées également
MERGE Si l'entité à modifier possède des entités dans l'association concernée, alors celle-ci sont modifiées (ou créées) également
REMOVE Si l'entité à supprimer possède des entités dans l'association concernée, alors celle-ci sont supprimées également
REFRESH Si l'entité à relire possède des entités dans l'association concernée, alors celle-ci sont relues également ("undo" des modifications)
DETACH Si l'entité à détacher possède des entités dans l'association concernée, alors celle-ci sont détachées également
@ManyToMany(mappedBy="pizzas",cascade= ?)private Collection<PizzaOrder> pizzaOrders = null;
READ N'existe pas ! car il s'agit du fetch=FecthType.EAGER
NONE N'existe pas ! car il s'agit du fetch=FecthType.LAZY
Exemple 2/2public class PizzaOrder implements Serializable {...@ManyToMany(fetch=FetchType.LAZY) @JoinTable(name="pizzadetail", joinColumns=@JoinColumn(name="order_id"), inverseJoinColumns=@JoinColumn(name="pizza_id"))private Collection<Pizza> pizzas = null;....__________________________
public class Pizza implements Serializable {...@ManyToMany(mappedBy="pizzas")private Collection<PizzaOrder> pizzaOrders = null;...
idem OneToMany d'un cotéFacultatif,
100
Configuration JPALa configuration de la persistance par JPA est dansMETA-INF/persistence.xml<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="PizzaPU"> <jta-data-source>java:/PizzaDS</jta-data-source> <class>fr.isen.eleve.todo.pizza.biz.EndUser</class> <class>fr.isen.eleve.todo.pizza.biz.Pizza</class> <class>fr.isen.eleve.todo.pizza.biz.PizzaOrder</class> <properties> <property name="showSql" value="true"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" /> </properties> </persistence-unit></persistence>
ou create,create-drop,
update
101
Instructions JPA• La classe EntityManager manipule les données
• em.flush() : sauvegarde immédiate des modifications
• em.refresh(e) : annulation de modifications• em.createQuery(<requête en ejbQL avec :param >)• em.createNativeQuery(<requête en SQL>)• em.getTransaction().begin();• em.getTransaction().commit();
JPA SQL
em.persist(e) insert
em.merge(e) update
em.remove(e) delete
em.find(e.class,id)
select
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistanceunitname>");EntityManager em = emf.createEntityManager();
@PersistenceContext(unitName="PizzaPU")private EntityManager em;
Gestion des entités
...public void orderPizza(PizzaOrder po, EndUser eu) {EndUser eu = persistenceManager.find(eu.getClass(),eu.getId()); po.setCustomer(eu);persistenceManager.persist(po);...
obligatoire si CascadeType.ALL non défini
new
Non gérée
gérée
persit(), merge(),find(), query()
detach()garbage collector
Refresh() et cascade d'entité non gérée interdite
Exemple @Statelesspublic class FacturationBean implements FacturationRemote {
@PersistenceContextprivate EntityManager entityManager;
public void creerFacture(String numfact, double montant) {Facture fact = new Facture(numfact);fact.setMontant(montant);entityManager.persist(fact);
}
public Facture getFacture(String numfact) {return entityManager.find(Facture.class, numfact);
}
}
Définition de l'héritage
@Entity@Inheritance(strategy=SINGLE_TABLE)@DiscriminatorColumn(name="<nom_colonne>", discriminatorType=STRING,length=20)
@Entity@Inheritance(strategy=InheritanceType.JOINED)
1 seule table pour toutes les sous-classes
1 table par sous-classe – classe mère
@Entity@PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")
1 table par sous-classe – classe fille
@Entity@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
1 table par classe@MappedSuperClassClasse mère abstraite
Con
seil
léD
écon
seil
lé
EJB-QL• Langage proche de SQL
– « select p from Pizza p » – From sur les classes au lieu des tables – Respectez la casse dans le nom de la classe
(package facultatif)
– "update" et "delete"– "inner join", "group by… having",– "order by"–
public List<Facture> listFactures( ) {Query q = em.createQuery("select po from PizzaOrder
fetch po.pizzaswhere po.customer.lastname like
=:lastname");q.setParameter("lastname","perez");return q.getResultList();
}
Liste des commanes avec leur client dont
le nom commence par :lastname
avec leur factures
ou q.getSingleResult() ou q.executeUpdate()selon les requêtes
Annotation de Callbacks d'une
entitée• Méthodes appelées par le
persistenceManagerAnnotation de callback Description
@PrePersist Avant insertion en base
@PostPersist Après insertion en base
@PreUpdate Avant mise à jour en base
@PostUpdate Après mise à jour en base
@PreRemove Avant suppression en base
@PostRemove Après suppression en base
@PreLoad Avant lecture en base
@PostLoad Après lecture en base
Bean Validation• Validation de données dans une instance• Contraintes déclarées par annotations java
@NotNull@Size(max=50)public String getNom()
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();Validator validator = factory.getValidator();Set<ConstraintViolation<DeveloppeurSeniorBean>> constraintViolations = validator.validate(personne);if (constraintViolations.size() > 0 ) {
Déclaration de contrainte
Validation
String Int, Long Float, Double
Date
@NotNull @Min @DecimalMin @Future
@Size @Max @DecimalMax
@Past
@Pattern
Bonnes pratiques JPA• Utiliser java.lang.Long pour l'id technique• Utiliser java.util.Set pour les associations• Toujours déclarer le type de fetch dans les
associations • Privilègier FecthType.LAZY sur toutes les associations
o Utiliser "join fetch" dans les requêtes JPQL
• Utiliser @NamedQuery• Utiliser une Query d'update plutôt que
t = em.find(Thing.class,id); t.setF(t); em.flush();
• Définir les entités JPA puis générer les tables lorsqu'il n'y a pas d'existant
Exemple @NamedQuery
@Entity@Table(name="pizza")@NamedQueries(
@NamedQuery( name="findAllPizzas", query="select p from Pizza p" )
)public class Pizza implements Serializable{
Backup Slides
EJB versus API REST & WebService
• Les API REST fournissent des ressourceso API de type CRUD basée sur HTTP ou HTTPS avec XML ou JSON;o portables entre plusieurs technologies (java, .Net, PHP, C++, etc.) ;o adaptées au web (utilisation des verbes du protocole HTTP).
• Les WebServices fournissent des serviceso fonctions plus évoluées que de simple CRUD, (services "métier") ;o Avec des définition stricte (WSDL) qui facilite l'outillage et la génération de
code;o Portables entre plusieurs technologies (java, .Net, PHP, C++, etc.).
• Les EJB fournissent des services transactionnels distribuéso transactions (commit, rollback) réparties sur plusieurs serveurs ;o Complété par des services techniques : sécurité, persistance, etc.o limités à la technologie javao limités au réseau local.
Déclaration de la sécurité par annotation
• @Stateful• @RolesAllowed( { "frontoffice",
"backoffice" } )• public class EndUserManagerBean ...
• L'identité (nom) d'un client est aussi appelée « Principal »
• Les rôles et les « Realm » (user /password) sont déclarés par configuration au niveau du serveur
• chaque serveur dispose de mécanismes spécifiques
Déclaration de la sécurité par DD
<assembly-descriptor>... <security-role> <description>Application front-office</description> <role-name>front-office</role-name> </security-role> <method-permission> <role-name>front-office</role-name> <method> <ejb-name>EndUserManager</ejb-name> <method-name>authenticate,chgPassword</method-name> </method> </method-permission></ assembly-descriptor>
Définition de rôle
Permissions accordéesà un rôle
JMS
MDB • Message Driven Bean• EJB pour les appels asynchrones
• L'appelant n'attend pas la réponse pour continuer son travail
• Exécution sur réception d’un message– Méthode onMessage( )– Utiliser les files de message JMS pour stocker les messages à traiter et
les réponses
• Un serveur JEE fournis des files JMS– Messages point à point : 1 émetteur, 1 destinataire – Message publish/subscribe : 1 émetteur, n destinataires abonnés– Garantie de stockage – Garantie de livraison des messages– Possibilité de retry
exemple MDB
Administration
JMS
BD
MDB StockHandler
MDB Order
Entity Bean Stock
TX
Serveur EJB
Appli :ClientJMS
publier
Envoi message
Mise à jour
JNDI
Topic Queue
créer
bind
QCF
créer
exemple MDB (2)public class StockHandlerBean implements javax.jms.MessageListener {… public void onMessage(Message message) { ... sh = (StockHome)initialContext.lookup("java:comp/env/ejb/Stock"); queue = (Queue)initialContext.lookup("java:comp/env/jms/Orders"); … MapMessage msg = (MapMessage)message; pid = msg.getString("ProductId"); qty = msg.getString( "Quantity"); cid = msg.getString("CustomerId"); Stock stock = sh.findByPrimaryKey(pid); stock.decreaseQuantity(qty); … qs = session.createSender(queue); TextMessage tm = session.createTextMessage(); String m = "For CustomerId = "+cid+" ProductId= "+pid+" Quantity= "+qty; tm.setText(m); qs.send(tm); ... }}
MDB : Annotations• @MessageDriven(activationConfig = {
@ActivationConfigProperty( propertyName="destination", propertyValue="SampleQueue"),@ActivationConfigProperty( propertyName="destinationType", propertyValue="javax.jms.Queue")}
Spring MVC• Définition de la servlet dispatcher dans web.xml• Annotations
o @Controller pour chaque classe Contrôleuro @RequestMapping(value = "/chemin")
• return ModelAndView• Taglib SpringMVC?
WebService et style de WSDL
EncodingMessage
Literal Encoded
RPC WSI-compliant
type des paramètres non précisé : polymorphisme impossible
Appel non validable par XSD : non WS-I compliant
Polymorphisme possible dans les appels de SOAP
Plusieurs appels de méthodes possibles en un seul appel SOAP
Document WSI-compliant
type des paramètres non précisé : polymorphisme impossibleméthode non précisé : un seule méthode par appel SOAP
non WSI-compliant
Polymorphisme impossible
Configuration mod_proxy_balancer
<Proxy balancer://mycluster>BalancerMember http://192.168.1.50:80BalancerMember http://192.168.1.51:80</Proxy>ProxyPass /test balancer://mycluster
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED<Proxy balancer://mycluster>BalancerMember http://192.168.1.50:80 route=1BalancerMember http://192.168.1.51:80 route=2ProxySet stickysession=ROUTEID</Proxy>ProxyPass /test balancer://mycluster
Répartition Simple et sans état
Répartition simple avec affinité de session
Répartition de charge depuis le serveur JEE
• TODO JBOSS
Maven• Projet défini dans une fichier POM pom.xml• Arborescence de projet type• Définition des dépendances entre projets
o <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.1</version> <scope>test</scope></dependency>
• Commandes de base :o mvn clean, compil, package, install, tomcat:deploy
• Utilisable depuis Eclipse
• Suite sur le support de cours "introMaven" de C. Dumoulin
Spring IoC• TODO : assemby.xml, context.xml• Utiliser Jetty• Assembler
Historique des WebServices vs CORBA
SOAPWSDLUDDI
CGI
ebXMLWSFLWS-PolicyWS-PolicyAssertionsWS-PolicyAttachmentWS-Policy FrameworkWS-SecurityPolicyWS-SecureConversationWS-DiscoveryWS-InspectionWS-EventingWS-AddressingWS-RoutingWS-ReferralMTOMWS-EnumerationWS-Transfer
CORBA
Concurrency Naming
Transaction Property
Trading Security
Externalization Persistence
Life cycle Event
Licensing Time
19982000
2004..
1991-2000
RPC
1976
1993HTTP
1991XML-RPC
EJB
1999