Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
1
Documents > J2SE APIs > J2EE APIs > Bibliographical references > Description of All Components
2
Applications Web 1 Appel d’une page HTML (browser/telnet), appel d’une servlette (telnet, FORM) Création/appel d’une servlette en WebLang, en WTP 2 La servlette affiche un lien sur le fichier de la FORM. Elle affiche la FORM elle-même. utilisation de sendRedirect 3 Passage des données par String, par Java bean. <Usebean>. Source JSP. Une seule JSP pour le tout. 4 Créer un CMP bean. Voir dans Hypersonic. Initialiser au moyen d’une servlette. 5 Relation pays – ville – capitale. Connecter les composants. Mettre le code dans des session beans. 6 Session bean retournant une collection provenant d’une relation. Parcours de cette relation dans une servlette 7 Villes d’un pays, pays d’une capitale, pays d’une ville. Effacement d’une ville. Remplissage au moyen de ant 8 Test 9 Liste de villes dans un rich client. Client avec un topic. Diffusion de messages. Jeu papier-caillou-ciseaux. 10 Jeu sur une FSM. 11 Struts: bibliothèque. 12 Struts: enregistrement des utilisateurs vérifiés par un manager 13 Test
3
J2EE Java php Websphere CVS Weblogic Visual Age .net ant RMI Eclipse
JDO Hybernate Java J2EE MySQL Javascript HTML Entity Bean JSF Servlet Cookie XML JBoss JSP MDBean taglib Tomcat Struts Rechercher: J2EE, PHP, Apache
4
LAMP (pas présenté) DB Linux, Apache, MySQL, PHP Server Client Network
Browser DB PHP <html> <head> <title>Test PHP</title> </head> <body> <?php echo ‘Bonjour '; ?> </body> </html> Network
5
Application Web sur J2EE
Tomcat JBoss Server Session EJB DB Client proxy Browser Entity EJB proxy Servlet Entity EJB x.html proxy Network
6
Pages HTML et Servlettes
Livre Software Engineering Sections 7.5, 7.7
7
Page HTML <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Tests/test</title> <script type="text/javascript"> function init() { // Javascript alert("Bonjour") } </script> </head> <body onload="init()"> Contenu de la page </body> </html>
8
Elements HTML <h1>Un grand titre</h1> <p>Un paragraphe</p> <table cellspacing="6" cellpadding="6" border="1" bgcolor="yellow"> <tr> <td bgcolor="#FFE0E0"> ligne1 <br> colonne 1</td> <td bgcolor="#E0E0FF"> ligne1, colonne 2</td> </tr> </table>
9
Elements actifs dans une form
<form method="get" name="record" action=" <input type="text" name="txInput1"/> <br> <input type="text" name="txInput2" value="initial"/> <input type="button" name="something" value="button"/> <input type="checkbox" name="checkB1" value="aaa"/>AAA <input type="checkbox" name="checkB2" value="bbb"/>BBB <input type="radio" name="radioB" value="ccc"/>CCC <input type="radio" name="radioB" value="ddd"/>DDD
10
Sélections <p> <select name="simpleSelection"> <option value="eee">EEE </option> <option value="fff">FFF </option> </select> </p> <p> <select multiple name="multipleSelection"> <option value="hhh">HHH </option> <option value="jjj">JJJ </option> </select> </p>
11
Autres éléments <p><input type="hidden" name="myValue" value="not_seen"/> </p> <p> <textarea name="thetext" rows="8" cols="80"> ha ! ha ! ha ! </textarea> </p> <p> <button name="button" value="button" type="button"/> Click<br> <img width="100" src="green.gif“ alt="wow"> </button> </p> <p><input type="submit" name="button"/> <input type="reset"/> </p> </form>
12
Form Envoyé au serveur (une seule ligne)
<form method="get" name="record" action=" . . . elements des pages précédentes . . . </form> Envoyé au serveur (une seule ligne) &txInput2=initial &simpleSelection=eee &myValue=not_seen &thetext=+++++ha+!+ha+!+ha+!%0D%0A++ &button=Envoyer
13
Upload de fichiers <form method="post" name="upform"
action=" enctype="multipart/form-data"> <input type="file" name="uploading"/> <input type="submit"/> </form>
14
Accès au serveur HTML Browser (client) Tomcat, Apache . . . (serveur)
HTML: Test.html <A HREF="URL">link</a> Internet
15
Servlet Objet généralisé Possède une méthode doGet
Serveur Web Browser Servlet doGet() { … } URL avec paramètres Objet généralisé Possède une méthode doGet Est exécuté dans un serveur Web Appelé par un browser
16
Servlet qui lit les données entrées dans des champs
Bouton submit
17
Formulaire HTML <form action=“http://localhost:8080/test">
<input type=“submit” name=“add“> <input type=“text” name=“val"> </form>
18
Formulaire HTML (Paragraphe 7.5.2)
<form action=“ add: <input type=“submit” name=“add"> <p> val: <input type=“text” name=“val"> </form>
19
Appeler une servlette Browser Serveur JBoss servlet: Test.java
HTML page <form action="URL"> <input type = "text" name="field"> </form> servlet: Test.java Internet Exécution de Java page HTML
20
Servlette: traitement des données
public class Test extends HttpServlet { public void doGet ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { PrintWriter out = response.getWriter(); response.setContentType("text/html"); out.println ("<html><body>"); out.println ("<h1>Title</h1></body>"); } Javadoc J2EE La page html est produite automatiquement quand la méthode se termine.
21
Classes Http Servlet HttpServletRequest.html, ServletRequest.html
HttpServletResponse.html, ServletResponse.html HttpSession.html
22
Décodage d’un paramètre dans une servlette (voir J2EE Javadoc)
<form action=" <input type = text name = "txtInp"> Servlette yyy
23
Décodage d’un paramètre dans une servlette (voir J2EE Javadoc)
Navigateur valueParam = request.getParameter("txtInp"); dans la servlette valueParam.equals("yyy") Java
24
Production du contenu d’une page HTML par une servlette
java.io.PrintWriter out = response.getWriter(); out.println(“<h1>Titre</h1>”);
25
WebLang Crée les sources des composants,
les fichiers auxiliaires et les fichiers ant
26
Fichier .cg http://ltiwww.epfl.ch/WebLang/Modules.html#servlets
servlet SomeServlet { package servletPack; public void someCall (PrintWriter out, String name, double number) { out.println(name + " " + number); }
27
Module servlet en WebLang
servlet TestServlet { package packageName; int attribute; // dangereux public void add ( PrintWriter out, int number) { attribute += number; out.println(attribute); } public void sub (int number) { attribute = number; determine la form HTML
28
WebLang génère les fichiers:
html: InputForms <FORM action= "test"> a b m1 c m2 servlet: Test.java doGet() { . . . } m1(int a, String b) { } m2(String c, long d) { }
29
Avec plus de détails html: InputForms servlette: Test.java
<form action= "test"> <input ... name="a"> <input ... name="b"> <submit name="m1"> </form> <input ... name="c"> <submit name="m2"> servlette: Test.java doGet() { a = getParameters(“a”); m1(a, b); or m2(c, d); } m1(int a, String b) { } m2(String c, long d) { }
30
Préparation et chargement d’une servlette
Eclipse fichier.cg CodeGen myServlet.java @web doGet() { } xdoclet packaging web.xml projet.ear WebLang Navigateur Serveur web.xml myServlet.java myPage.html
31
Compilation d’un fichier.cg
bouton droit de la souris Compilation d’un fichier.cg
32
Déploiement d’un projet
WebLang Run As… > CGxdoclet.xml Run As… > CGpackaging.xml
33
Démarrer le serveur JBoss
Il est possible de gérer le serveur JBoss, ou d’autres serveurs à partir d’Eclipse. Les manipulations de préparation sont présentées ci-dessous. Ces manipulations préparent en même temps les librairies nécessaires aux projets J2EE
34
Nettoyer les programmes dans JBoss
Eliminez les programmes et structures laissés par l'étudiant précédent. Pensez à le faire dans les leçons suivantes également ! Effacez les répertoires tmp, data, log et work qui se trouvent dans C:\jboss GA\server\default Effacez tous les fichiers se terminant par .ear (pour archive) ou .war se trouvant dans C:\jboss GA\server\default\deploy Pour arrêter JBoss, cliquer le carré rouge dans la fenêtre serveur et attendez qu’il se termine!
35
Singleton (pour l’exercice)
Une seule instanciation, à la première utilisation. public class BD { private static BD localBD = null; public static BD getBD() { if (localBD==null) { localBD = new BD(); } return localBD; private String name; // autres paramètres // utilisation BD.getBD().list();
36
Définition d’une classe en WebLang
class MyClass { package aPackage; import java.util; access remote; // optional, default is local outputchannel myCh (queue, A); // future Bean bean; public void aMethod() throws Exception { System.out.println("a method called"); Bean b = beanHome.create(); // future b.method(); } Génère une classe habituelle et introduit les références et fonctions qui permettront de la charger dans le serveur.
37
Affichage pour dépanner
System.out.print(“xxx”); affiche ses sorties dans la console d’Eclipse
38
Exercice 1: une application Web
nom incorrect Servlet login() cancel() Page HTML entrée Singleton (à la place d’une base de données) correct Servlet store(String x) list() quit() Page HTML entrée transition entre états introduction de données
39
Structure et scripts d’un projet JEE
40
Structure d’un projet JEE
servlets librairies JEE fichier d’appel de tous les objets générés fichiers d’appel des méthodes des servlets JSP définition des servlets scripts ant de préparation tout est génére à partir de ce fichier
41
xDoclets Outil standard pour créer une partie des
fichiers indiqués dans les pages précé- dentes
42
xDoclet crée le fichier web.xml
import javax.rmi.PortableRemoteObject; . . . /** * name = "MyServletServlet" * display-name = "TestServlet" * description = "A simple Servlet" * url-pattern = "/MyServlet" */ public class TestServlet extends HttpServlet { public void doGet (HttpServletRequest request,
43
Script ant pour appeler XDoclet généré automatiquement par WebLang
<?xml version="1.0" encoding="UTF-8" ?> <project default="N2" name="XDoclet Generator"> <path id="xdoclet.classpath"> <pathelement location="C:/jboss GA/server/default/lib/javax.servlet.jar"/> <fileset dir="C:\eclipse\xdoclet_lib/"> <include name="*.jar" /> </fileset> </path> <target name="N2" description="Servlet/Taglib"> <taskdef classpathref="xdoclet.classpath“ classname="xdoclet.modules.web.WebDocletTask“ name="webdoclet" /> <webdoclet destDir="WEB-INF" verbose="true" mergeDir="WEB-INF/merge"> <fileset dir="src"> <include name="package/AServlet.java" /> <deploymentdescriptor Servletspec="2.3" /> </webdoclet> </target> </project>
44
Contenu de web.xml généré automatiquement par xdoclet
<servlet> <servlet-name>MyServletServlet</servlet-name> <display-name>MyServlet</display-name> <description><![CDATA[A simple Servlet]]></description> <servlet-class>serv.MyServlet</servlet-class> </servlet> <servlet-mapping> <url-pattern>/MyServlet</url-pattern> </servlet-mapping> <!-- look for "servlet-name" tutorial in Google! -->
45
CGPackaging.xml <!--********************WEB class*******************--> <target name="WEB" description="Lecon3.war"> <jar destfile="lib/Lecon3.war"> <zipfileset dir="WebContent/WEB-INF" prefix="WEB-INF"> <include name="*.xml"/> <include name="*.wsdd"/> </zipfileset> <zipfileset dir="WebContent/WEB-INF/lib" prefix="WEB-INF/lib" includes="**/*.jar"/> <zipfileset dir="bin" prefix="WEB-INF/classes"> <include name="applicationWeb/Login*.class"/> <include name="applicationWeb/Manage*.class"/> <zipfileset dir="lib" prefix="WEB-INF/lib"> <include name="Lecon3-CL.jar"/> <zipfileset dir="WebContent" prefix=""> <include name="appliWeb/Manager.jsp"/> <include name="applicationWeb/Login.html"/> <include name="applicationWeb/Manage.html"/> </jar> </target>
46
Session de client (Paragraphe 7.8.5)
Chaque client a une zone pour ses variables Lié à la session par les cookies La servlette retrouve les variables de l’appelant automatiquement
47
Objets de session dans des servlettes
Client 2 Client 21 Serveur Client 1 (cookie) Servlet y = session.getAttribute("xx"); Java bean “xx” Client 2 (cookie) Java bean “xx”
48
Trouver les Java beans dans la session
public public void doGet ( HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(); MyObject myObject = new MyObject (); session.setAttribute("myObject", myObject); x = session.getAttribute("myObject"); . . .
49
JSP: Java Server Page (Section 7.8) JSP (exécuté sur le serveur)
≠ Javascript (exécuté dans le browser) voir Servlets and JavaServer Pages: A Tutorial
50
Comparaison servlettes - JSPs
public class Test extends HttpServlet { public void doGet (request, response) { out.println ("<html><body>"); out.println ("<h1>"); out.println ( x.toString() ); out.println ("</h1></body>"); } } Servlette <html><body> <h1> <%= x.toString() %> </h1></body JSP
51
Création d’une JSP JSP ( code ) ( + ) ( html ) Servlet Java source
JSP compilateur Java compilateur Exécution JSP ( code ) ( ) ( html ) Servlet Java source Servlet Java code html html serveur browser Réseau
52
Exemple d’une page JSP (Vue globale)
<html> <head><title>File</title></head> <body> <h1>Example</h1> <%! declarations %> <% code Java %> Nouvelle valeur de l'attribut: <%= attribute %> <p> <form action=" <input type="text" name="attribute"/> <input type="submit"/> </form> </body> </html>
53
Page JSP: déclaration <%! declarations %>
<!-- déclaration d’attributs Attention, le même objet servlette est partagé par tous les clients -->
54
Page JSP: affichage Affichage d’une valeur de variable:
Affichage du retour d’une méthode: <%= myClass.text() %> <% // Java code out.println( "Text <p>" ); %>
55
Conditional statements
<% if (error!=null) { %> <b>Error: <%=error.message()%><b> <% } %>
56
Conditional statements (code généré)
if (error!=null) { out.print(“<b>Error:”); out.print(error.message(); }
57
URL d’une JSP
58
Autres instructions JSP
pageimport="packName.*" %> request, response et session sont définis par défaut dans une JSP
59
Standard Tags JSP jsp:include jsp:useBean jsp:setProperty
jsp:getProperty jsp:forward jsp:plugin Voir PDF ou HTML et Servlets and JavaServer Pages: A Tutorial
60
Applet <jsp:plugin type="applet" code="package.HorlogeApplet"
width="370" height="50"> </jsp:plugin>
61
Session / Java bean <jsp:useBean id = "myForm" scope = "session"
class = "app.InputForm" /> <jsp:setProperty name = "myForm" property = "attribute" value ="<%= x %>" /> class InputForm { int attribute; // getter/setter créés au moyen d’Eclipse }
62
Utiliser un tag non standard
Définition: taglib uri = "pack/myTag.tld" prefix = "tag"%> Utilisation: <tag:myTag/>
63
Classe tag Correspondante
package pack; import java.io.IOException; /** * name = "myTag" * description = "A test class for tags" */ public class myTag extends TagSupport { public int doStartTag() { JspWriter out = pageContext.getOut(); out.println("I am a tag"); return 33; } } Classe tag Correspondante
64
Description d’un tag: MyTag.tld
Créé par les xDoclets ?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" " <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>xdoclet-build</short-name> <tag> <name>myTag</name> <tag-class>pack.myTag</tag-class> <description><![CDATA[A test class for tags]]></description> </tag> </taglib>
65
Où se retrouve le fichier JSP compilé en Java?
C:\jboss-4.0.0\server\default\work… (n’est compilé que lorsqu’on l’appelle)
66
Java bean package p; public class Result implements Serializable {
public Result() { } // optionnel int xxx; public int getXxx() { return xxx; } public void setXxx(int xxx) { this.xxx = xxx; Dans Eclipse: sélectionner int xxx clic-droit sur la sélection Source > Generate Getter…
67
Utilisation d’une session et d’un Java bean
sendRedirect Page HTML Servlet Page JSP Servlet Session client (cookies) Java bean Java bean Java bean
68
Architecture de l’exercice 1
Java Bean Résultat Page.jsp Affichage résultat Nouvelle entrée Servlette.java Calcul
69
Architecture de l’exercice 2
Même Page.jsp Page.jsp Calcul + Affichage résultat Nouvelle entrée Page.jsp Calcul + Affichage résultat Nouvelle entrée Java bean Résultat
70
Database access with the help of persistent objects
EJB: Enterprise Java Beans
71
Web Application (J2EE) DB Server Client Network Container Container
JBoss Server Container Container Session EJB Entity EJB DB Client Tomcat Browser Servlet proxies Container Entity EJB x.html Network
72
Client-server Application (J2EE)
JBoss Container Container Client Session EJB Entity EJB Client proxies DB Container Network Entity EJB
73
CMP entity beans (Container Managed Persistency)
BMP, Bean Managed Persistency will not be studied as there are better alternatives
74
Specification of CMP entity beans in WebLang
CMP bean: relations methods attributes finders / creators
75
Definition of an object in WebLang
cmpbean Town { package geo; String name; // DB attributes int numero; public void myMet (String s) { System.out.println(s); } // creators - finders
76
CMP Bean: method create
cmpbean Person { package beans; String firstName; String lastName; // attributes = DB columns int age; public Person createPerson ( String firstName, String lastName ); // age not initialised } // the arguments of the create must correspond // to the attributes. They are stored in the latter.
77
Creation and use of an object in WebLang
Town t ; Country c ; t = townHome.create("Lausanne"); c = countryHome.create("Switzerland"); System.out.println( t.getName() ); c.setName( "Suisse" );
78
CMP Bean: finder method
Town findByName (String s) { query = "SELECT OBJECT(o) FROM Town o WHERE o.name=?1" } // more details later
79
Find an object in WebLang
Town t ; try { t = townHome.findByName("Lausanne"); } catch (javax.ejb.FinderException fe) { t = townHome.create("Lausanne"); } System.out.println( t.getNumber() );
80
Servlet using a bean servlet myservlet { package servlets;
public void newPerson ( PrintWriter out, String firstName, String lastName, int age) throws Exception { Person aPers; aPers = personHome.createPerson (firstName, lastName); aPers.setAge(age); } // it is a simple means to test CMP beans, an html // file that calls this servlet is created automatically
81
Java Client (remote) jclient Ouf { package clientPack;
public void method1 (String s1, String s2) { Person aPers; Course aCourse; aPers = personHome.createPerson("a", s1); aCourse = courseHome.createCourse("prof", s2); } // WebLang generates automatically a remote access
82
Reading the HSQLDB database
Select: service=Hypersonic (fifth line under jboss) Select invoke (below startDatabaseManager) Look at the task bar and let the DB window appear. Click View/Refresh tree in this window Examine the tables (Command > Select …)
83
Fichiers auxiliaires des CMP entity beans (générés par WebLang et par XDoclet)
84
Files generated by WebLang and by the xDoclets
src/control Game.java GameCMP.java GameLocalHome.java GameLocal.java GameHome.java GameUtil.java sources of the beans interfaces of the proxies
85
Parts of a CMP entity bean
EJBContainer servlet other EJB XxxxLocalHome create findByPrimaryKey Xxxx ejbCreate ejbPostCreate ejbFindByPrimaryKey ejbLoad ejbStore userMethods XxxxEntityBean XxxxLocal userMethods
86
Instantiation of a persistent object
InitialContext lookup 1 XxxxHomeProxy create findByPrimaryKey 2 client servlet bean XxxxObjectProxy userMethods EJB EJB XxxxObjectProxy userMethods EJB XxxxObjectProxy userMethods 3
87
Lookup to get a home proxy
TownLocalHomeProxy townLocalHomeProxy = null; Context context = new InitialContext(); Object ref = context.lookup("store_PersonLocal"); townLocalHomeProxy = (TownLocalHomeProxy) PortableRemoteObject.narrow ( ref, TownLocalHomeProxy.class ); // narrow = cast from object to TownLocalHomeProxy
88
Class specifying a CMP entity bean
package store.ejb; import javax.ejb.EntityBean; import javax.rmi.PortableRemoteObject; /** * name = "Customer" * display-name = "CMP Entity Bean" * description = "Description of the CMP Entity Bean" * view-type = "both" * type = "CMP" * primkey-field = "pk" * jndi-name = "store_CustomerRemote" * local-jndi-name = "store_CustomerLocal" * class ="java.lang.Long" */ public abstract class Customer implements EntityBean { EntityContext entityContext; . . .
89
CMP entity bean (primary key)
/** * Attribute Pk is used as primary key by default. */ public abstract java.lang.Long getPk(); public abstract void setPk(java.lang.Long pk); * Default remove method RemoveException public void ejbRemove() throws RemoveException { }
90
CMP entity bean: Attributes
/** * A pair of getter / setter for each attribute * * view-type = "both" */ public abstract String getAtt() ; public abstract void setAtt(String att) ;
91
Control files generated by the xDoclets
META-INF ejb-jar.xml jboss.xml jbosscmp-jdbc.xml
92
Extrait de ejb-jar.xml (src/META-INF)
<display-name>CMP Entity Bean</display-name> <ejb-name>Patient</ejb-name> <home>predimed.PatientHome</home> <remote>predimed.Patient</remote> <local-home> predimed.PatientLocalHome </local-home>
93
Fichier.ear deploy Fichier.ear
application.xml // références les fichiers ci-dessous Fichier.jar // contient les EJBs Fichier.war // contient les servlettes, passé à Tomat <module> <ejb>Test.jar</ejb> </module> <module> data/jboss-app/application.xml <web> <web-uri>Test.war</web-uri> <context-root>/Test</context-root> </web>
94
Session beans (Pattern de façade)
95
Collections gérées par une session bean
Server collection JBoss Entity EJB Client Session EJB Entity EJB Entity EJB Browser Servlet proxies Entity EJB proxies proxies Network Les collections (relations) doivent être gérées dans des session ou CMP beans
96
Une session bean en WebLang
sbean ControllerSession { package beans; state Stateful; // optionnel String st; public ControllerSession create (String st); public void newPerson (String firstName, String lastName, int age) throws Exception { Person aPers; aPers = personHome.createPerson(firstName, lastName, age); } }
97
Bean Managed Transaction
sbean ControllerSession { package beans; (Container managed transaction) transaction Bean; // optionnel, par défaut une CMT est créée state Stateful; // optionnel String st; public ControllerSession create (String st); public void newPerson (String firstName, String lastName, int age) throws Exception { Person aPers; beanContext.getUserTransaction().begin(); // optionnel aPers = personHome.createPerson(firstName, lastName, age); beanContext.getUserTransaction().commit(); // abort() } }
98
Relations entre CMP beans
99
1:N Relation Y X N 1 4 23 8 5 WebLang, object view: cmpbean X {
relation <hasY 1:N hasX> Y; } 23
100
1:1 Relation (bidirectionnelle)
Y X 23 4 23 WebLang: cmpbean X { relation <hasY 1:1 target hasX> Y; } cmpbean Y { relation <hasX 1:1 hasY> X;
101
N:M Relation 23 4 27 X 8 Y 24 23 5 5 23 8 27 8 24 4
102
N:M Relation (toujours bidirectionnelle)
WebLang: cmpbean X { relation <possessesY N:M hasX> Y; …attributes… } cmpbean Y { relation <hasX N:M possessesY> X;
103
xdoclets pour les relations
/** * Implementation of the relationship: getCollection * view-type = "local" * name="Courses-Students-NM" * role-name="Courses-N-role" * target-ejb="Students" * target-role-name="Students-M-role" * target-multiple="yes" * style="relation-table" * table-name="CoursesXStudents" * related-pk-field = "pk" * fk-column="students_pk" * fk-constraints = "false" * fk-column = "courses_pk" */ public abstract java.util.Collection getStudentsN(); xdoclets pour les relations
104
Operations concernant les relations entre beans
(WebLang)
105
Relations utilisées dans les pages suivantes
cmpbean Country { relation <hasCapital 1:1 isCapitalOf> Town; relation <hasTown 1:N isLocatedIn> Town; } cmpbean Town { relation <isCapitalOf 1:1 hasCapital> Country; relation <isLocatedIn N:1 hasTown> Country;
106
Utilisation d’une référence bidirectionnelle 1:1
Country-Capital Town t = townHome.create("Bern"); Country c = countryHome.create("Switzerland"); t.setIsLocatedIn(c); System.out.println( t.getIsLocatedIn().getName() ); // setIsLocatedIn est automatiquement définie quand on spécifie la relation isLocatedIn
107
Addition d’un élément à une relation
Country (1) – Town (N) Town v ; Country c ; t = townHome.create("Lausanne"); c = countryHome.create("Switzerland"); t.setIsLocatedIn(c); // 1:1 side t = townHome.create("Bern"); c.addHasTown(t); // 1:N side
108
Déposer une relation et y accéder
Collection collection = aCountry.getHasTown(); Iterator it = collection.iterator(); while (it.hasNext()) { // Java 1.4 System.out.println( ( (Town) it.next() ) .getName() ); }
109
Déposer une relation et y accéder
Collection collection = aCountry.getHasTown(); for (Object o: collection) { // Java 1.6 System.out.println( ( (Town) o ) .getName() ); }
110
addHasTown est introduit par WebLang
void addHasTown(t) { getHasTown().add(t); } // standard add et remove de Collections // ajouté automatiquement par WebLang removeHasTown(t) { getHasTown().remove(t); Les collections doivent être manipulées à l’intérieur de transactions
111
Résumé des relations et de leurs méthodes
indication in Xxxx Other end in Yyyy methods available <elemY 1:1 elemX> Yyyy no relation <elemX 1:1 target elemY> Xxxx <collX 1:N elemY> Xxxx Yyyy y = getElemX() setElemX(yyyy) <elemY 1:1 target elX> Yyyy no relation <elX 1:1 elemY> Xxxx Yyyy y = getElemY() setElemY(yyyy) <collY 1:N elemY> Yyyy no relation <elemX N:1 collY> Xxxx Collection y = getCollY() setCollY(collection) addCollY(yyyy), removeCollY(yyyy) <collY N:M collX> Yyyy no relation <collX N:M collY> Xxxx
112
Comparaisons entre objets
CB h1 = cBHome.create("5"); CB h2 = cBHome.findH("5"); if (h1 == h2) ; // pas valable ! if (h1.getPrimaryKey().equals(h2.getPrimaryKey()) System.out.println("2 x the same bean"); if ( ((Long)h1.getPrimaryKey()).intValue() == ((Long)h2.getPrimaryKey()).intValue()) System.out.println("2 x the same bean");
113
(voir exemple du paragraphe 11.2.6.8)
Finders (voir exemple du paragraphe )
114
Finder retournant un objet ( WebLang )
Course findCourse (java.lang.String name) { query = "SELECT OBJECT(o) FROM Course o WHERE o.courseName=?1" }
115
Source d’un finder /** * Pays CMP Entity Bean * * @ejb.bean
* name = "Pays" * display-name = "CMP Entity Bean" * description = "Description of the CMP Entity Bean" * view-type = "both" * type = "CMP" * primkey-field = "pk" * jndi-name = "geo_PaysRemote" * local-jndi-name = "geo_PaysLocal" * class ="java.lang.Long" * signature = "java.util.Collection findByVilleAvecM (java.lang.String s)" * query = "SELECT OBJECT (p) FROM Pays p, IN (p.contient) v WHERE v.nom LIKE CONCAT(?1, '%')" */ public abstract class PaysBean implements EntityBean { Source d’un finder
116
Build/classes/META-INF/ejb-jar.xml <query> <query-method>
. . . <query> <query-method> <method-name>findVille</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql><![CDATA[SELECT OBJECT(v) FROM Ville v WHERE v.nom=?1]]> </ejb-ql> </query>
117
Tester si un objet existe en WebLang
Country c = null; try { c = countryHome.findByName("Switzerland"); } catch (javax.ejb.FinderException fe) { c = countryHome.create("Switzerland"); }
118
Finder retournant une collection
(ici la table entière) java.util.Collection findCourses () { query = "SELECT OBJECT(o) FROM Course o" } Note: les collections retournées par les finders peuvent être manipulées dans servlets.
119
Références cascadées 1:1
Option findOptionByProf (java.lang.String profName) { query = "SELECT OBJECT(s) FROM Option o WHERE o.course.profName=?1" } // le finder doit être inclus dans le CMP bean // qui définit l’objet retourné
120
Relation 1:1 retournant une collection de membres appartenant à la relation
public java.util.Collection findCountryByCapital (java.lang.String capital) { query = "SELECT c.capital FROM Country c WHERE c.capital.name LIKE CONCAT('_', CONCAT(?1, '%‘)) " } // On utilise une collection, parce qu’on suppose que // plusieurs beans peuvent correspondre au même critère
121
Relation 1:N Country <contains 1:N isIn> Town
public java.util.Collection findCountryByTownName (java.lang.String name) { query = Country "SELECT OBJECT(c) FROM Country c, IN (c.contains) t WHERE t.name=?1" }
122
Relations 1:N cascadées Country : contains Town : hasNb Number
public java.util.Collection findCountryByNumber (int number, java.lang.String name) { query = "SELECT OBJECT(n) FROM Country c, IN (c.contains) t, IN (t.hasNb) n WHERE c.name = CONCAT("%", ?2) AND n.value < ?1" }
123
Relations cascadées A 1:1 B 1:1 C 1:1 D - dd
public A findAByX (java.lang.String name) { query = "SELECT OBJECT (o) FROM A o WHERE o.b.c.d.dd=?1" }
124
Relations cascadées An 1:N Bn 1:N Cn 1:N Dn - dd
public java.util.Collection findA(java.lang.String name) { query = "SELECT OBJECT (o) FROM An o, IN(o.bnN) bx, IN(bx.cnN) cx, IN(cx.dnN) dx WHERE dx.dd=?1" }
125
Relations en cascade (la query retourne un An)
An 1:1 Bn 1:N Cn 1:1 Dn - dd public java.util.Collection findAn (java.lang.String name) { query = "SELECT OBJECT (o) FROM An o, IN(o.bn.cnN) cx WHERE cx.dn.dd=?1" } // à introduire dans un bean An
126
(la query retourne un Bn)
Relations en cascade (la query retourne un Bn) An 1:1 Bn 1:N Cn 1:1 Dn - dd public java.util.Collection findBn (java.lang.String s) { query = "SELECT o.bn FROM An o, IN(o.bn.cnN) cx WHERE o.aa=?1" } // à introduire dans un bean Bn car il retourne une // collection de Bn
127
Transactions
128
Transactions dans les session beans
transaction Bean; La transaction n’est pas gérée automatiquement, le développeur doit insérer le code qui la gère.
129
Relation N:M manipulée depuis une session bean
Cours Etudiants N M Expérience: Enregistrer un étudiant dans un cours Voir si l’étudiant est visible depuis le cours
130
beanContext.getUserTransaction().begin();
s1.addCourse(c1); // s1, s2 are students and s1.addCourse(c2); // c1,c2 courses s1.addCourse(c3); s2.addCourse(c3); System.out.println("Additions terminées"); Thread.sleep(10000); // suspendue pendant 10 sec pour voir // dans la base de données for (Students s : c3.getStudentsN()) { System.out.println("c3.collection"+s.getName()); } beanContext.getUserTransaction().commit();
131
Transactions CMP Bean A Transaction présente avant d’entrer B
CMP Bean B Transaction crée par le conteneur pour B
132
Dans le CMP bean (WebLang)
transaction RequiresNew; Dans la méthode du CMP bean beanContext.setRollbackOnly();
133
Transaction avant l’exécution
Types de transaction Type de transaction Transaction avant l’exécution Réaction du conteneur Required présente aucune est gardée une nouvelle RequiresNew Mandatory erreur
134
Appels locaux/distants
Les programmes situés sur des ordinateurs autres que le serveur peuvent accéder à une session beans ou une CMP entity beans de la même manière que les servlets ( mais par le biais de XxxRemoteHomeProxy ) Il ne peuvent pas manipuler les relations des CMP beans (pour plusieurs raisons)
135
Classes / jclients de WebLang
WebLang gèrent les home interfaces, les entités CMP et les noms des classes des session beans de même que les input/output channels dans la plupart des modules En particulier dans les jclients et dans les classes. Note: les classes doivent contenir l’indication access Remote; si elles ne sont pas dans le serveur.
136
class or jclient Module
jclient Ouf { package clientPack; inputchannel varName (topic, "TopicName") { … } void method1 (String s) { Person aPers; Course aCourse; aPers = personHome.createPerson(s+"pers"); // CMP bean aCourse = courseHome.createCourse(s+"course"); } void method2 () { List aList; String str = "Text = "+listHome.create().text(); // session bean System.out.println(str); } }
137
Struts
138
Basic structure of struts
PersonManagement SportManagement Servlet Servlet Servlet Servlet JSP JSP sport person sportName location personName sportForm The forms are saved in the HTTP session Under the name derived from the class ! personForm
139
Output of data (same for input)
sportForm location Struts sportForm.setLocation("xxx") JSP <bean:write name="sportForm" property="location"/> <html:text name="location"/> No direct connection !
140
Basic structure of struts
PersonManagement SportManagement Servlet Servlet Servlet Servlet JSP JSP sport person 2 1 3 personName sportName location personForm sportForm The forms are saved in the client session Under the name derived from the class !
141
1 Librairies Struts: Action Form ( = java bean )
/** name="personForm" */ public final class PersonForm extends ActionForm { private String name; public String getName() { return (this.name); } public void setName(String name) { this.name = name; } // ActionForm has code to fill in the form from the URL
142
2 Librairie JSP pour Struts: HTML Form
JSP: input.jsp <h3>personForm.sportForm</h3> <html:form action="/personManagement"> sportName <html:text property="name"/> <html:submit/> </html:form> // Plusieurs paramètres de l’action sont définis dans struts-config.xml // en particulier une form est attribuée à cette action et name est le nom d’un // champ de cette form
143
3 Struts: Action Servlet
public final class PersonManagement extends Action { PersonForm f; public ActionForward execute (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { try { f = (PersonForm) form; f.getName(); return (mapping.findForward("sport")); } catch(Exception e) { // trap exceptions that may occur in your servlet e.printStackTrace(); // you will get better error messages ! return (mapping.findForward("error")); } } } // L’action form passèe comme argument est automatiquement // remplie à partir des arguments de l’URL 3 Struts: Action Servlet
144
Fichier auxiliaire: struts-config.xml
(généré par xDoclet) <action-mappings> <action path="/personManagement" type="management.PersonManagement" // servlet class name="personForm" // name in HTTP session scope="session" input="/pages/Error.jsp" unknown="false" validate="true" > <forward name="sport" // name that can be used as next page path="/pages/sport.jsp" redirect="false" /> </action>
145
Action Forms CMP Beans
Main personForm[] Action forms Course Person[] PersonForm finder ou getCollection Person Recrée une collection et copie ses éléments dans l’autre collection CMP beans // code prochaine page
146
Action Forms CMP Beans
Course Person[] per Main personForm[] per PersonForm PersonForm Person Person Pseudo-code course.setPer( new ArrayList() ) for (each main.per[]) { x = personHome.create(per[].attributes) course.addPer(x) }
147
- Action forms, - arrays of action forms, - trees of action forms
148
Java beans composés person In/out Action Action In/out Input sport job
SportManagement In/out PersonManagement Action Action In/out Input sport job jobName location personName jobName location sportName location jobName location personName jobName location jobName location sportForm[ ] jobName location jobName location Pas supporté jobName location personForm jobForm[] sportName location jobForm[ ] sportForm // Toutes les Action Form envoyées à // une action doivent avoir le même type
149
Tree of action forms /** * @struts.form name="personForm" */
public final class PersonForm extends ActionForm { . . . private SportForm sportForm; // sub-form public SportForm getSportForm () { return (this.sportForm); } public void setSportForm (SportForm sportForm) { this.sportForm = sportForm;
150
Array of sub-action forms
( x[ ] or Collection or Set ) /** name="personForm" */ public final class PersonForm extends ActionForm { . . . private Collection sportForms; public Collection getSportForms () { return (this.sportForms); } public void setSportForms (Collection sportForms) { this.sportForms = sportForms;
151
Reference to an attribute of an Action Form
In the action servlet f.getName(); In the JSP <html:text property="name"/> the form in which name is looked for is linked to the JSP by a definition introduced in struts-config.xml
152
Reference to an attribute of a Sub-Action Form
In the action servlet f.getSportForm().getName(); In the JSP <html:text property="sportForm.name"/> the form is linked to the JSP within struts-config.xml
153
Reference to an array of Sub-Action Forms
In the action servlet (first element ! ) o = ((ArrayList) f.getSportForms(); name = ((SportForm) o.get(0)).getName(); // f is linked to the JSP in struts-config.xml In the JSP <html:text property="sportFormN[0].name"/> // The element passed to the property can be // an ArrayList or an array such as String[]
154
Tags in the JSP and the Struts
<jsp:useBean id="managementForm" scope="session" class="man.ManagementForm"/> <bean:write name="managementForm" property="warning" filter="false"/> // prints the value of the property on the page
155
HTML form in a JSP <h3>PetForm</h3>
<html:form action="/Supplier_State_0_Action" > <html:hidden name="petForm" property="<%= page_prop_token %>" value="<%= pageId %>" /> <table border=0><tr> <tr><td> name <td><html:text property="name"/> <tr><td colspan=2 align=center> <html:submit property="submit">submit</html:submit> </table> </html:form>
156
Array in an HTML form <html:form action="/Supplier_State_0_Action" > <html:hidden name="petForm" property="<%= page_prop_token %>" value="<%= pageId %>" /> <table border="0" cellspacing="1"> <tr><td> <table border="0" width="100%"><td>subName</table> <td> <table border="0" width="100%"><td>number</table> <td> <table border="0" width="100%"><td>check</table> <tr><td> <table border="0" cellspacing="1"></table> <!-- tableau transparent suivant <tr><td colspan=10 align=center> <html:submit property="submit">submit</html:submit> </table> </html:form>
157
Iteration on the array (or collection)
<logic:iterate name="petForm" property="thingN" id="item1" indexId="index1"> <tr><td> <table border="0" width="100%"<%=color[index1.intValue()%2]%>> <td> <bean:write name="item1" property="subName"/> </table> <td> <td><bean:write name="item1" property="number"/> <table border="0" width="100%" <%=color[index1.intValue()%2]%>> <td><html:checkbox property='<%="thingN["+index1.intValue()+"].check"%>'/> </logic:iterate> cette valeur est retournée dans l’URL
158
Internationalization (a.k.a. i18n)
Properties defined in resources/application.properties resources/application_fr.properties Introduced in the JSPs by <bean:message key=“struts.page.form.text"/> (see the file for details) If the browser is set to French application_fr.properties is used
159
Translation of the properties
Copy resources/application.properties to resources/application_fr.properties and edit the content of the new file
160
Struts in WebLang Architecture pour: Machine à états finie
Gestion des pages
161
Assurer une confirmation!
L’utilisateur clique le bouton Confirm L’ordre est exécuté par le serveur L’utilisateur clique le bouton BACK du browser Il reclique Confirm erreur: double entrée Comment le serveur évite-t-il le doublon ?
162
Eviter le doublon Chaque page contient un hidden field avec un numéro unique Avant de lire les paramètres de la page, on vérifie que le numéro est celui de la dernière page envoyée Cela implique un code homogène
163
State Machine Login Register Fill a cart Confirm the cart
Show the bill Confirm the order (only once)
164
WebLang use of the JSPs and servlets
personName sportName location state == 1 transition from state 1 state = 2 state == 2 transition from state 2 state = 1 JSP JSP State_1 State_2
165
WebLang use of the JSPs and servlets
sportName location FSM bean FSM bean JSP JSP Where to start ? In the bean! Same bean, but different states personName
166
Finite State Machine in a Struts
page_0 not confir- med showBasket page_1 1 confirmed 2 page_2 OK
167
WebLang Module : states and pages
struts PersonManagement { package management; stateMachine state State_0 > person; state State_1 > job; FSM page person { personForm; personForm.sportForm[ ]; personForm ("Comment", submitName) ; }
168
WebLang Module : Finite State Machine
state State_0 > supply; state State_1 > supplyConfirmation; switch (sessionState) { case State_S: sessionState = State_0; break; case State_0: Pet pet = petHome.create( petForm.getName() ); sessionState = State_1; case State_1: if (supplyConfirmation.getConfirmation()) } // Pure Java code
169
WebLang Module : Forms (Java beans)
form SportForm { package fmPack; String sportName; int location); } form PersonForm { // sub-form String name ; JobForm jobForm; SportForm sportFormN [ ] ; form JobForm { String jobName; int location;
170
Different display formats
page SomePage { petForm; // displays all the fields petForm.thingN[ ]; petForm.bbb (MySubmit); // displays a MySubmit button petForm.ccc (Cancel); // display a button petForm.aaa (); // displays no button }
171
Struts JSP struts Supplier { . . . page supply { petForm;
petForm.thingN[ ]; } form PetForm { package fp; String name; Thing thingN[]; form Thing { String subName, int number, boolean check;
172
Selection of the visible fields
page SomePage { petForm () { readwrite nom; hidden age; } petForm.thingN[ ]; petForm.bbb (MySubmit); }
173
Selection of the visible fields
page SomePage { petForm () ; petForm2<PetForm> () petForm.thingN[ ]; petForm3<PetForm>.bbb (MySubmit); }
174
Characteristics of the fields
hidden message readonly readwrite radio (aaa,bbb) combo (aaa,bbb) password readonly radio (aaa,bbb) | readwrite | combo (aaa,bbb) | password // last lines: one of each group, e.g. readwrite radio
175
Struts in WebLang Action Forms CMP bean JSPs Action Servlet Struts
browseForm.petForm[ ] (form) Struts Action Forms browser (JSP) not confir- med basket.petFrom[ ] (form) showBasket 1 showBasket (JSP) confirmed order- registered (JSP) 2 PetOrder status = ordered OrderItems* (CMP+CMR) CMP bean OK JSPs Action Servlet
176
Three tiers (overview)
browseForm.petForm[ ] (form) Buying Struts browser (JSP) Administrator Struts PetOrder status = toBeChecked OrderItems* (CMP+CMR) areYouThe- Administrator (JSP) not confir- med basket.petFrom[ ] (form) showBasket login showBasket (JSP) 1 checkOrders (JSP) confirmed OrderForm.petForm[ ] not accept (form) select 1 order- registered (JSP) 2 confirmed OK PetOrder status = ordered OrderItems* (CMP+CMR) SendSupplierPO MDBean Queue Three tiers (overview) file PetOrder status = awaitInvoice OrderItems* (CMP+CMR) Display Business Layer Database + Dataflow Business Layer Display
177
Prints in WebLang out print println Struts print JSP 1 In the Struts, WebLang automatically defines a stream named out, which contains methods out.print(“xxx”); and out.println(“yyy”); the text produced is automatically printed on the next JSP
178
Sub-FSMs display enter application display ignore start timeout enter
next previous start timeout enter display 2 ignore display_francs 1 display_euros
179
Sub-FSM Struts A Struts B State_0 State 0 State_1 State_3 State_S
(start) State 0 State_R (redirect) 1st return 1st call subsequent calls State_1 Goto B Continue State_3 Return 2nd return
180
Page_1 Page_0 Groupe Personnes Introduire personnes/ groupes
EntrerGroupe EntrerGroupe EntrerGroupe Lister/former groupes Page_2 EntrerPersonne EntrerPersonne EntrerPersonne Nom groupe Personnes Quitter Quitter nomP NomG v Entrer Quitter
181
JMS: Java Message Services
Channels (queues, topics, durable topics) Message driven beans Architecture
182
Message Driven Bean queue, topic
Server Clients Sender queue/topic MDBean Listener queue topic SynReceiver
183
Types de canaux Each message is rec-eived by a single client Queues
Topics Each client receives all messages Durable Topics Each client receives all messages, even if it is temporarily discon-nected Requires (only in input) subscription name username, passwd
184
Création de queues et topics
Queolques queues et topics sont créés quand le serveur JBoss est démarré: A, B, C, D, testTopic (lire les informations imprimées quand JBoss démarre) La queue ou le topic d’un MDBean est créé à la création du MDBean. On peut créer d’autres queues et topics en modifiant les fichiers qui définissent l’environment de JBoss selon
185
Canaux disponibles dans WebLang:
MDBeans (1 input / 0-n outputs) Servlets, (0-n outputs) JSPs, Struts CMP beans (0-n outputs) jclient, class (0-n inputs / 0-n outputs)
186
Listener de queue / topic
Client inputchannel ch { } Serveur Object operation1() operation2() queue topic Listener Needs C:\jboss-4.0.0\client\jbossall-client.jar
187
Envoyer des messante à une queue ou un topic
Client outputchannel ch { } Server Object ch.send(message) queue topic proxy
188
Module client ou classe en WebLang
jclient MyClient { // or class package myPackage; inputchannel inputName (topic, "MDBTopic") { String s = ((TextMessage)msg).getText()); varName.publish(msg); } outputchannel varName (topic, "testTopic"); public void method(String s) { }
189
Listener généré par WebLang
public class alarmChListener implements javax.jms.MessageListener { public void onMessage(javax.jms.Message msg) { try { System.out.print ((javax.jms.TextMessage)msg).getText(); } catch (Exception t) { t.printStackTrace(); } } } Text specifié dans l’inputchannel
190
Lecture synchrone // Lire la queue en mode synchrone
// (attente de 5 secondes au plus) tmpQueue = (javax.jms.Queue) queueCtx.lookup("queue/C"); queueObj = queueSession.createReceiver(tmpQueue); for (;;) { Message msg = (Message) queueObj.receive(5000); if (msg == null) System.out.println("Timed out"); else System.out.println(msg.getText()); }
191
Message driven bean
192
Module MDBean en WebLang
Pas de nom (à la diférence des autres) mdbean MyMDB { package myPackage; inputchannel (queue, "MDBQueue") { String s = ((TextMessage) msg).getText()); varName.send(msg); } outputchannel varName (queue, "B"); // executed when a message arrives
193
Module servlet en WebLang
servlet MyClient { package myPackage; // pas d’inputchannel possible ! outputchannel varName (queue, "A"); public void method(String s) { TextMessage tm = queueSession.createTextMessage(s); varName.send(tm); }
194
Proxy d’un topic (généré by WebLang, similaire pour les queues)
public void newTopicEnv(String name, String passwd) throws Exception { Object tmp = initCtx.lookup("UIL2ConnectionFactory"); TopicConnectionFactory tcf = (TopicConnectionFactory) tmp; topicConn = tcf.createTopicConnection(name, passwd); topicSession = topicConn.createTopicSession( false, javax.jms.TopicSession.AUTO_ACKNOWLEDGE ); topicConn.start(); }
195
Connexion à un topic (généré by WebLang)
tmpTopic = (javax.jms.Topic) initCtx.lookup("topic/testTopic"); fromTopic = topicSession.createSubscriber(tmpTopic); fromTopic.setMessageListener(new fromTopicListener());
196
Exemples d’architecture
197
Exemple d’environnement pour un jeu dans lequel un dé tourne parmis les joueurs (une fois qu’ils se sont enregistrés) Server Browser Initialise le jeu game Servlet CMP beans (nom de partie) Java client Java client topic Java client
198
Java client topic GUI setUsername () getUsername () setPosition ()
setError () Java client Message Listener onMessage () { } topic GUI Listeners actionPerformed() { } invokeLater Business layer FSM () { }
199
Classes in WebLang class Business { package ppp;
outputchannel ch (topic, “testTopic”); access Remote; public Business(LoterieGUI gui) { this(); this.gui = gui; }
200
La machine d’état est exécutée sur le thread du GUI et le sur le thread qui gère le topic
java.awt.EventQueue.invokeLater( new Runnable() { public void run() { // access to the GUI } } );
201
Machine à états finie public void transition(String source) { try {
switch (state) { case 0: if (source != "username") return; game = gameHome().findByName(gui.getGameName()); . . . state = 1; break; case 1: if (source != "nextmove") return; state = 2; case 2: if (source != "done") return; game.moveTerminated(); } } catch (Exception e) { }
202
Web Services SOAP Simple Object Access Protocol ou Service Oriented Architecture Protocol HTTP remote call SOA Service oriented architecture WSDL Web Services Description Language UDDI Universal Description Discovery and Integration ( tombe dans l’oubli )
203
Schéma d’un web service
Application (standalone) stub Serveur remote object == Java bean Application (sur serveur) stub
204
Documentation sur la création des Web Services
Help > Help Contents > Documentation
205
Bottom Up: Java bean service
. . . <wsdl:types> <schema elementFormDefault="qualified" <element name="grow"> <complexType> <sequence> <element name="p" type="impl:Person"/> </sequence> </complexType> </element> WSDL package web; public class Test { public Person grow(Person p){ p.setSize(p.getSize()+1); return p; }
206
Web Services Description Language (WSDL)
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace=" /" xmlns:wsdlsoap=" <!--WSDL created by Apache Axis version: 1.3 Built on Oct 05, 2005 (05:23:37 EDT)--> <wsdl:types> <schema elementFormDefault="qualified" <element name="grow"> <complexType> <sequence> <element name="p" type="impl:Person"/> </sequence> </complexType> </element> . . . <wsdl:port binding="impl:TestSoapBinding" name="Test"> <wsdlsoap:address location=" </wsdl:port> </wsdl:service> </wsdl:definitions>
207
Creation d’un Web Service
L’accès à une application est fait au moyen de servlettes développées dans le projet Axis et qui appellent l’objet désigné par l’utilisateur
208
Test du service (après avoir compilé la classe)
Service Explorer WebContent/wsdl/Xxx.wsdl > right click > Web Services > Test with Web Services Explorer JSP de test classe.java > right click > Web Services > Generate Sample JSPs
209
Top Down: Java bean service
WSDL file (par exemple sur une page WEB qui décrit le service) On obtient un squelette à compléter
210
Web service en WebLang (seuls les types simples supportés)
webservice Simple { package xxx; public int add (int i, int j) { return i+j; }
211
From an action form to a CMP bean and vice-versa
Transfer of data From an action form to a CMP bean and vice-versa
212
Action Forms CMP Beans
Main resultFormN Action forms Course personN PersonForm finder or getCollection Person Recreates a collection and copies one into the other member by member CMP beans // code next page
213
Action Forms CMP Beans
String courseName = result.getCourseForm().getName(); // reads an action form java.util.Collection<Person> coll = personHome.findPersonInCourse(courseName); java.util.Collection<PersonForm> c = new ArrayList<PersonForm> (); for (Person aPerson: coll) { // scan the collection of CMP beans PersonForm personF = new PersonForm(); personF.setFirstName(aPerson.getFirstName()); personF.setLastName(aPerson.getLastName()); c.add(personF); // creates the collection of action forms } result.setPersonFormN( c );
214
Checking which submit has been clicked
If (submit.equals(“OK”)) { } page supply { petForm.thingN [ ] (OK, Cancel) readwrite name; } }
215
Exercise Lottery application implemented with Struts
Draw first a diagram with the html forms, the action forms, the state machine and the database WebLang modules CMP bean: Customer name Generated automatically struts: Lottery - register(String) - login() - displayResults() html: lottery Start struts CMP bean: Token number
216
EJB - Hibernate 3 Hibernate 3 allows the beans to be either attached to or detached from the database The beans can thus be used as action forms too, which avoids the tedious transfers from the beans to the action forms The version we will use is based on introduced in Java 1.5 See the page WebLang about Hibernate Quelques commentaires ont été ajoutés sous les transparents dans les pages suivantes
217
Annotations (replace xDoclets)
/** name="jeton" */ @Entity public class Jeton implements java.io.Serializable { . . . @Id(generate = GeneratorType.AUTO) public long getId() { return id; } @ManyToOne public loterie.Client getClient() { return (client); Note: En WebLang, tous les ejb3 doivent se trouver dans le même package Ces annotations sont générées automatiquement par WebLang
218
WebLang module (same as cmpbean, but no finders, no creators: they are made in the user’s space)
ejb3 MyCountry { package myPackage; relations (Town=1:N); String name; int number; public Country(String name) throws Exception { this.name = name; } public String toString() { String str = "Country id=" + getId() + " name=" + getName(); java.util.Collection<Town> tlist = getTownN(); for (Town town: tlist) { str = str + "\n Town=" + town; return (str);
219
Configuration parameters
config { deploypath = "C:/jboss-4.0.0/server/standard/deploy/"; hibernate_driver = "org.hsqldb.jdbcDriver"; hibernate_url = "jdbc:hsqldb:hsql://localhost:1701"; // for the JBoss database as prepared here hibernate_username = "sa"; hibernate_password = ""; hibernate_dialect = "org.hibernate.dialect.HSQLDialect"; hibernate_dbauto = "create-drop"; // if present, // recreates the tables at each restart } Les paramètres de configurations sont indiqués ci-dessus pour la configuration standard utilisée dans les salles d’ordinateurs
220
Use of a Hibernate bean javax.persistence.EntityManager em;
javax.persistence.EntityTransaction tx; em = hibernate_utility.Manager.open(); tx = em.getTransaction(); tx.begin(); Country c = new Country("Switzerland"); em.persist(c); c.setNumber(1291); // DB updated at commit tx.commit(); // tx.commit() or tx.rollback(); hibernate_utility.Manager.close(); Les instructions de stockage dans la base de données doivent être placées dans des transactions, ouvertes par les 5 premières lignes de ce transparent et fermées par les deux dernières. L’instruction em.persist(c) attache l’objet c à la transactions, qui mémorise toutes les modifications et les exécute au plus tard au commit Toutes les modifications peuvent être annulées par l’instruction rollback
221
Finding objects with Hibernate
javax.persistence.Query qt; qt = em.createQuery( "select t from Town t where t.name=?"); qt.setParameter(1, name); try { town = (Town)qt.getSingleResult(); } catch (javax.persistence.EntityNotFoundException enf) { town = new Town(name); em.persist(town); } La recherche d’objets de la base de données est faite au moyen des instructions ci-dessus. Si elle est effectuée dans une transaction (pas montrée ici), l’objet est automatiquement attaché et les modifications qu’il subira seront mémorisées et effectuées au commit. Sinon, l’objet est retourné en tant que simple objet. Dans l’exemple ci-dessus, on vérifie si l’objet existe. Si ce n’est pas le cas, on le crée ce qui demande une transaction.
222
Finding lists of objects with Hibernate
javax.persistence.Query qt; qt = em.createQuery("select t from Town t"); try { townN = (Collection)qt.getResultList(); } catch (Exception e) { // some error } Pour rechercher une collection, on utilise la méthode indiquée ci-dessus.
223
Using Hibernate objects (size() not written - lazy evaluation)
tx.begin(); . . . proprietaire = qt.getSingleResult(); Collection c = proprietaire.getVoitureN(); // The elements of the // collection are retrieved only when needed tx.commit(); for (Voiture v: proprietaire.getVoitureN()) { out.println(v.getName()); // accessed outside the transaction } 09:22:28,774 INFO [STDOUT] org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: package.Proprietaire.voitureN, no session or session was closed Lorsque l’on recherche un objet qui possède une collection d’autres objets dans une relation, les objets de la relations ne sont recherchés dans la vbase de données que lorsque le programme les appelle (lazy évaluation) pour optimiser les transferts. Donc la transaction doit encore être ouverte à cet instant. Lorsque les objets de la collections sont affichés dans un tableau dans une JSP, la transaction a déjà été fermée, ce qui provoque l’erreur indiquée ci-dessus. À suivre
224
Using the objects of a Hibernate relationship outside the transaction
Owner Car 1 N tx.begin(); . . . owner = qt.getSingleResult(); owner.getCarN().size(); tx.commit(); required to force the computation (other functions may also be used) for (Car c: owner.getCarN()) { otherwise not available out.println(v.getName()); } Pour assurer que le programme recherche les éléments de la collection, il suffit d’appeler une fonction qui les utilise, par exemple size() comme cela est fait ci-dessus.
225
Both Action form and Hibernate bean
ejb3 MyCountry extends strutsStateMachine.StateForm { package myPackage; relations (Town=1:N); String name; int number; } Un bean Hibernate peut être également un e ActionForm (les deux sont des Java beans). Pour cela, il suffit d’hériter de StateForm comme ci-dessus. Dans ce cas, il ne faut pas définir la form, elle est automatiquement déclarée par le compilateur WebLang. Les relations d’un ejb3 correspondent aux sous-formes des ActionForm. Cela est valable aussi bien pour les tableaux (1:N, N:M) que pour les objets simples (1:1)
226
Create and Persist an Action Form
// town is assumed to be a form filled in by the user town.setId(0); // be sure it has not been left // attached by some previous action javax.persistence.EntityManager em; javax.persistence.EntityTransaction tx; em = hibernate_utility.Manager.open(); tx = em.getTransaction(); tx.begin(); em.persist(town); tx.commit(); hibernate_utility.Manager.close(); } Avant de rendre un objet persistant, il faut être sûr qu’il n’est plus attaché. Cela est fait en mettant son ID à zéro. Il faut éviter qu’il soit dans une transition à ce moment-là, évidemment.
227
Transactions and display
No transaction Transaction Transaction get from the DB display, let the user modify the data store into the DB Must reconnect the bean to a transaction La situation représentée ci-dessus est fondamentale dans les applications Web. Les deux transactions en vert sont effectuées sur deux appels d’un utilisateur, par exemple dans deux transitions d’un automate construit dans un Struts. Dans la première, on lit des données de la base de données, puis après avoir fermé la transaction, on passe l’objet ou les objets (par exemple le Java bean en jaune) à la couche de présentation (JSP, GUI…) pour que l’utilisateur puisse le modifier. Losque le système doit entrer les modifications dans la base de données, il faut réintroduire l’objet dans un nouvelle transaction (si on gardait la première, le système se bloquerait rapidement). Pour cela, il faut utiliser les instructions présentées sur le prochain transparent. Java bean (ActionForm/EJB)
228
Reconnect an EJB3 to the DB
tx.begin(); // a first call to a servlet em.persist(x); tx.commit(); …Displaying… tx.begin(); // a subsequent call y = em.merge(x); // copy x to a new y y.setName(“new value”); // and persists y tx.commit(); Le merge détermine s’il y a déjà un objet avec le même ID dans la transaction. Si c’est le cas, il copie les données du nouvel objet dans l’objet attaché et il retourne l’objet de la transaction. Si ce n’est paas le cas, il crée un nouvel objet dans la transaction, copie les données du nouvel objet dans l’objet nouvellement créé et retourne ce dernier (ce qui n’est pas très rusé, mais il semble que ce soit bien le cas).
229
Handling a relationship
Owner Car tx.begin(); em.persist(owner); for (Car c: cars) { em.persist(c) owner.add(c); c.setCar(owner); // indispensable to introduce it into the DB } // because the reference is defined in table car tx.commit(); 1 N Les connections des relations ne sont pas effectuées automatiquement dans les deux sens, il faut le faire explicitement. La base de données n’est correctement mise à jour que si l’objet qui correspond à la table de la base de données est connecté à la relation: setXxxx(yy) pour une relation xxxx -> yy (1:1) setXxxx(yy) pour une relation yy -> xxxx (1:1 target ou 1:N)
230
Merging a relationship (could be done by using cascade)
Owner Car 1 N tx.begin(); x = em.merge(owner); for (Car c: owner.getCarN()) { x.add(em.merge(c)); // reintroduce the merged } // objects into the new object owner = x; // optional: remettre l’objet dans son pointeur request.getSession().setAttribute(“owner”, owner); // et tx.commit(); // dans la servlet-session x : Owner c : Car 1 N Quand un objet est “mergé”, les collections de ses relations ne sont pas automatiquement “mergées”. Pour cela il faudrait utiliser l’annotation cascade qui n’est pas encore disponible en WebLang. Pour une relation simple (1:1), il suffit de “merger” l’objet référencé. Pour une relation N:M ou 1:N, il faut “merger” chaque objet et pour cela les copier dans la collection du nouvel objet comme indiqué ci-dessus. Note: La première version de ce transparent utilisait un moyen un peu plus compliqué (et avec une erreur!)
231
SQL beans SQL beans have been devised at the EPFL: they present the same structure as Hibernate 3 (particularly within WebLang), but they only use JDBC and the standard SQL Much simpler to debug, as all statements may be traced within the debugger No home, the object must be created to hold the finder (instantiation by new)
232
SQL Bean Example sqlbean Town extends strutsStateMachine.StateForm { package appliT; relations ( Country = N:1, <isCapitalOf 1:1 hasCapital> Country); String name; public long findPK_OfTown() throws Exception { query = "SELECT * FROM Town WHERE name=$name;" } } TownN { public void findN_TownList(String s) throws Exception { query = "SELECT * FROM Town WHERE name>$s" }
233
Use of an SQL bean // we assume that country has been created // and filled by the Struts mechanism case State_1: long pkC = country.findPK_OfCountry(); if (pkC!=0) { country.reloadAll(pkC); } else { country.store(); } country.addTownN(town); // town.setCountry(country); // either this line or the line // above; the second one is // called automatically
234
Finders TownN tn = new TownN();
try { tn.findTownList(“N”); } catch (weblangUtils.SQLException we) { System.out.println(“Not found”); } for (Town t: tn) { System.out.println(“t.getName()); } …………………………………………………………….. TownN { String name; public void findTownList (String s) throws Exception { query = "SELECT * FROM Town WHERE name>$s" } } Finders
235
FSM of the SQL beans o = new Xxx() Detached object o.set(o1) o.add(o1)
o.store() o.set(null) o.remove(o1) pk=o.findPKXx() o.findXx() o.reload(pk) o.store() o.delete() Attached object pk!=0 o.delete() Linked object pk==0 o.reload(0) o.delete() o.set(null) o.remove(o1) o.set(o1) o.add(o1) o.reloadAll() o.storeAll() Attached + linked + connected object pk!=0 rel!=0 o.deleteAll() o.reload() o.reloadAll() o.update() o.updateAll()
236
States of the SQL objects
Detached: The object has been instantiated Attached: The object has a corresponding set of data in the database Linked: The object is embedded in a structure, but it has no primary key Attached, linked The object is available in the database, and connected: as well as in memory, within some relationship
237
Operations of the SQL beans
store Copies the data of the object into the database, new primary key inserted in the object findXxx Query method returning a DB row, the object must be instantiated before the method is called findPKXxx Returns the value of the primary key (or 0), method may also throw an exception reload(pk) Method copies the data of the object into a DB row with primary key pk update Dual of the reload, updates the database row that has the PK found in memory
238
More Operations delete Removes the data in the database, not the memory, resets the object’s primary key set, add Establishes connections between remove the objects, the two directions of the relationship are handled storeAll Call all the objects bound by deleteAll a relationship (not recursively) reloadAll updateAll
239
RMI Application interface interface Xxxx Xxxx Client Server Xxxx Xxxx
RemoteXxxx Xxxx (stub) Xxxx (skeleton)
240
RMI: inverse communication (by transmitting the stub)
Server rmiregistry Transfer (skeleton) Client 1 Transfer (stub) 2 myRemStub MyRemote (skeleton) MyRemote (stub) 3
241
RMI Module rmi Test { package rmis; public void print (String s) { System.out.println("X "+s); } } jclient Client { package rmis; Test x; // as Test corresponds to an rmi interface, // x is automatically initialized RemoteTest y; // y is not automatically initialized, the client // must call new RemoteConnection(true) public void print (String s) { try { x.print(s); } catch (Exception e) { e.printStackTrace(); } } }
242
Software Engineering
243
Application / implementation
Craig: ( Specifying software means components, interfaces, archit-ectures, or what is sometimes referred to as the "How". Specifying applications means features, capabilities, options, or what is sometimes referred to as the "What". So, it seems odd to me (i.e., Craig ) to use UML (a "how" language) as a universal specification language.
244
My View Actually, you want to describe the software, the how. The customer can often not read any schema and will require a fast prototype, which is indeed the software. Library (Librarian, book shelves, quiet room) Soft Library (simulator) (terminals, server, software) Each time a book is borrowed in the real library, the librarian borrows a book here = Borrow a book Look for a user A book has been lost Check differences Sort books Reserve a book Software application (terminals, server, software)
245
Three tiers (overview)
browseForm.petForm[ ] (form) Buying Struts browser (JSP) Administrator Struts PetOrder status = toBeChecked OrderItems* (CMP+CMR) areYouThe- Administrator (JSP) not confir- med basket.petFrom[ ] (form) showBasket login showBasket (JSP) 1 checkOrders (JSP) confirmed OrderForm.petForm[ ] not accept (form) select 1 order- registered (JSP) 2 confirmed OK PetOrder status = ordered OrderItems* (CMP+CMR) SendSupplierPO MDBean Queue Three tiers (overview) file PetOrder status = awaitInvoice OrderItems* (CMP+CMR) Display Business Layer Database + Dataflow Business Layer Display
246
Exercise of Software Engineering (8)
Creation of a stock exchange application. Customers are connected to the bank. The bank keeps a portfolio for each client, transmits the customer orders to the stock exchange. The stock exchange keeps an “order book” that contains the stocks that customers want to buy or sell, with the prices (or price range) they are willing to pay or get. Create a diagram that specifies a customer, a bank and a stock exchange, with CMP beans, queues, session beans… Create a diagram of the software system that will run the application, not of the application itself.
247
Exercice: Compléter la loterie pour que le client voie une annonce quand le manager a sélectionné les jetons Créer les fonctions qui permettent d’entrer des jetons depuis le client Java (rich client)
248
Loterie Client Serveur html généré Java bean: LotteryData
- constantes générales - client html: display_Manager - tireJetons(int) servlet: Manager - tireJetons(int) - afficheJetons() cmpbean: Client String nom 1 N html: display_GestionJeton - remplitJeton(int) - afficheResultats() servlet: GestionJeton - remplitJeton(int) - afficheResultats() sbean: AccesJetons - addJeton(Client, Jeton) - listeResultats(Client) cmpbean: Jeton int numero attente int etat gagnant perdant html: display_Enregistrement - enregistre(String) - login(String) servlet: Enregistrement - enregistre(String) - login(String) html généré
249
Loterie Browser Serveur Client Java bean: LotteryData
- constantes générales - client html: display_Manager - tireJetons(int) servlet: Manager - tireJetons(int) - afficheJetons() Client topic: testTopic cmpbean: Client String nom listener: class: LoterieGUI (created with Visual Editor) 1 N cmpbean: Jeton int numero attente int etat gagnant perdant
250
Loterie Browser Serveur Client Java bean: LotteryData
- constantes générales - client html: display_Manager - tireJetons(int) servlet: Manager - tireJetons(int) - afficheJetons() Client topic: testTopic cmpbean: Client String nom class: LoterieGUI - display: TextArea - login: TextField - tireJeton: TextField display(String) listener: 1 N cmpbean: Jeton int numero attente int etat gagnant perdant sbean: ClientBean - login(String) - tireJeton(int) invokeLater class: Business - login(String) - tireJeton(int)
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.