Building Web Applications with Java

Download Report

Transcript Building Web Applications with Java

1
Documents
http://ltiwww.epfl.ch/ProgrammationInternet
> J2SE APIs
> J2EE APIs
http://ltiwww.epfl.ch/WebLang
> Bibliographical references
> Description of All Components
Applications Web
2
3
php
Websphere
Weblogic
.net
Javascript
J2EE
Servlet
http://www.topjobs.ch/
Rechercher: J2EE, PHP, Apache
4
LAMP (pas présenté)
Linux, Apache, MySQL, PHP
Server
Client
PHP
<html>
<head>
<title>Test PHP</title>
</head>
<body>
<?php echo ‘Bonjour '; ?>
</body>
</html>
Browser
Network
DB
5
Application Web sur J2EE
Server
Session
EJB
Client
proxy
Browser
Servlet
proxy
Entity
EJB
x.html
proxy
Entity
EJB
Network
Tomcat
JBoss
DB
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="http://localhost:8080/xxxx">
<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>
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>
11
12
Form
<form method="get" name="record" action="http://localhost:8080/xxxx">
. . . elements des pages précédentes . . .
</form>
Envoyé au serveur (une seule ligne)
http://localhost:8080/xxxx?txInput1=
&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="http://localhost:8080/check"
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
Serveur Web
Browser
URL avec paramètres
•
•
•
•
Servlet
doGet() {
…
}
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=“http://localhost:8080/test">
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>
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 )
Javadoc J2EE
throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/html");
out.println ("<html><body>");
out.println ("<h1>Title</h1></body>");
}
}
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="http:www.epfl.ch/servletName//">
http://www.epfl.ch/servletName?txtInp=yyy
<input type = text name = "txtInp">
yyy
Servlette
23
Décodage d’un paramètre dans une servlette
(voir J2EE Javadoc)
Navigateur
http://www.epfl.ch/servletName?txtInp=yyy
valueParam = request.getParameter("txtInp");
valueParam.equals("yyy")
dans la servlette
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
@@deploypath="C:/jboss-4.2.3.GA/server/default/deploy/"
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
b
servlet: Test.java
doGet() {
...
}
m1(int a, String b) { ... }
m2(String c, long d) { ... }
m2
29
Avec plus de détails
html: InputForms
<form action= "test">
<input ... name="a">
<input ... name="b">
<submit name="m1">
</form>
<form action= "test">
<input ... name="c">
<input ... name="b">
<submit name="m2">
</form>
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
WebLang
fichier.cg
CodeGen
myServlet.java
@web
doGet() { }
Navigateur
xdoclet
packaging
web.xml
projet.ear
Serveur
web.xml
myServlet.java
myPage.html
31
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
http://ltiwww.epfl.ch/WebLang/JBossInit
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 !
1. Effacez les répertoires tmp, data, log et work qui se trouvent
dans
C:\jboss-4.2.3.GA\server\default
2. Effacez tous les fichiers se terminant par .ear (pour archive) ou
.war se trouvant dans
C:\jboss-4.2.3.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
Page HTML
login()
cancel()
entrée
Singleton
correct
Servlet
Page HTML
entrée
store(String x)
list()
quit()
(à la place d’une
base de données)
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
http://xdoclet.sourceforge.net/xdoclet/index.html
42
xDoclet crée le fichier web.xml
import javax.rmi.PortableRemoteObject;
...
/**
* @web.servlet
* name = "MyServletServlet"
* display-name = "TestServlet"
* description = "A simple Servlet"
* @web.servlet-mapping
* 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-4.0.4.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" />
</fileset>
<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>
<servlet-name>MyServletServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
<!-- look for "servlet-name" tutorial in Google! -->
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>
<zipfileset dir="lib" prefix="WEB-INF/lib">
<include name="Lecon3-CL.jar"/>
</zipfileset>
<zipfileset dir="WebContent" prefix="">
<include name="appliWeb/Manager.jsp"/>
</zipfileset>
<zipfileset dir="WebContent" prefix="">
<include name="applicationWeb/Login.html"/>
<include name="applicationWeb/Manage.html"/>
</zipfileset>
</jar>
</target>
45
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
Objets de session
dans des
servlettes
Client 21
47
Client 2
Servlet
Client 1
(cookie)
Java bean
“xx”
y = session.getAttribute("xx");
Serveur
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)
http://java.sun.com/products/jsp/docs.html
voir Servlets and JavaServer Pages: A Tutorial
50
Comparaison servlettes - JSPs
Servlette
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>");
}
}
JSP
<html><body>
<h1>
<%= x.toString() %>
</h1></body
51
Création d’une JSP
JSP compilateur Java compilateur
JSP
( code )
( + )
( html )
Servlet
Java
source
Servlet
Java code
serveur
http://www.ch/xxxx.jsp
Exécution
html
html
browser
Réseau
52
<html>
<head><title>File</title></head>
<body>
<h1>Example</h1>
Exemple d’une
page JSP
<%! declarations %>
<%
code Java
%>
(Vue globale)
Nouvelle valeur de l'attribut: <%= attribute %>
<p>
<form action="http://localhost:8080/Exercice3-WEB/File.jsp">
<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:
<%= 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
http://localhost:8080/Exercice3/File.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
http://java.sun.com/products/jsp/docs.html
Voir 2.0 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
package pack;
Classe
tag
import java.io.IOException;
Correspondante
/**
* @jsp.tag
*
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;
} }
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" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<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
Java bean
Servlet
Page JSP
Java bean
Session client (cookies)
Servlet
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
Page.jsp
Calcul +
Affichage résultat
Calcul +
Affichage résultat
Nouvelle entrée
Nouvelle entrée
Java bean
Résultat
70
Database access with the help
of persistent objects
EJB: Enterprise Java Beans
71
Web Application (J2EE)
Server
Container
Session
EJB
Container
Entity
EJB
Client
Browser
proxies
Servlet
Entity
EJB
Container
x.html
Network
Tomcat
JBoss
DB
72
Client-server Application (J2EE)
Server
Container
Client
proxies
Session
EJB
Container
Entity
EJB
Client
DB
Network
Entity
EJB
Container
JBoss
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
CMP bean:
WebLang
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
http://localhost:8080/jmx-console
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)
src/control
Files generated
by WebLang
and by the
xDoclets
Game.java
GameCMP.java
sources of the beans
GameLocalHome.java
GameLocal.java
GameHome.java
GameUtil.java
interfaces
of the
proxies
84
85
Parts of a CMP entity bean
EJBContainer
XxxxLocalHome
servlet
other
EJB
create
findByPrimaryKey
XxxxLocal
userMethods
Xxxx
ejbCreate
ejbPostCreate
XxxxEntityBean
ejbFindByPrimaryKey
ejbLoad
ejbStore
userMethods
86
Instantiation of a persistent object
InitialContext
lookup
1
XxxxHomeProxy
2
create
findByPrimaryKey
client
servlet
bean
3
XxxxObjectProxy
XxxxObjectProxy
XxxxObjectProxy
userMethods
userMethods
userMethods
EJB
EJB
EJB
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
package store.ejb;
import javax.ejb.EntityBean;
CMP entity bean
import javax.rmi.PortableRemoteObject;
/**
* @ejb.bean
* 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"
* @ejb.pk
* 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.
* @ejb.persistent-field
*/
public abstract java.lang.Long getPk();
public abstract void setPk(java.lang.Long pk);
/**
* Default remove method
* @throws RemoveException
* @ejb.remove-method
*/
public void ejbRemove() throws RemoveException { }
90
CMP entity bean: Attributes
/**
* A pair of getter / setter for each attribute
*
* @ejb.persistent-field
* @ejb.interface-method
* view-type = "both"
*/
public abstract String getAtt() ;
/**
* @ejb.interface-method
* view-type = "both"
*/
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>
</module>
94
Session beans
(Pattern de façade)
95
Collections gérées par
une session bean
Server
collection
Client
Browser
Session
EJB
Entity
Entity
Entity
EJB
EJB
EJB
Servlet
Entity
EJB
proxies
proxies
proxies
Network
JBoss
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
Y
1:N Relation
4
X
23
N
23
8
23
1
WebLang, object view:
cmpbean X {
relation <hasY 1:N hasX> Y;
}
5
23
100
1:1 Relation (bidirectionnelle)
X
Y
23
4
WebLang:
cmpbean X {
relation <hasY 1:1 target hasX> Y;
}
cmpbean Y {
relation <hasX 1:1 hasY> X;
}
23
101
N:M Relation
X
23
4
27
8
24
23
23
27
24
5
8
8
4
5
Y
102
N:M Relation (toujours
bidirectionnelle)
WebLang:
cmpbean X {
relation <possessesY N:M hasX> Y;
…attributes…
}
cmpbean Y {
relation <hasX N:M possessesY> X;
…attributes…
}
/**
* Implementation of the relationship: getCollection
* @ejb.interface-method
*
view-type = "local"
* @ejb.relation
*
name="Courses-Students-NM"
*
role-name="Courses-N-role"
*
target-ejb="Students"
*
target-role-name="Students-M-role"
*
target-multiple="yes"
* @jboss.relation-mapping
*
style="relation-table"
* @jboss.relation-table
*
table-name="CoursesXStudents"
* @jboss.relation
*
related-pk-field = "pk"
*
fk-column="students_pk"
*
fk-constraints = "false"
* @jboss.target-relation
*
related-pk-field = "pk"
*
fk-column = "courses_pk"
*
fk-constraints = "false"
*/
public abstract java.util.Collection getStudentsN();
xdoclets
pour les
relations
103
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
in Xxxx
<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
Collection y = getCollY()
setCollY(collection)
addCollY(yyyy),
removeCollY(yyyy)
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
Finders
http://ltiwww.epfl.ch/~petitpie/ProgrammationInternet/ejb-2_1-fr-spec.pdf
(voir exemple du paragraphe 11.2.6.8)
114
Finder retournant un objet
( WebLang )
Course findCourse (java.lang.String name) {
query = "SELECT OBJECT(o)
FROM Course o
WHERE o.courseName=?1"
}
115
/**
* Pays CMP Entity Bean
Source d’un finder
*
* @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"
* @ejb.pk
*
class ="java.lang.Long"
* @ejb.finder
*
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, '%')"
* @generated
*/
public abstract class PaysBean implements EntityBean {
116
Build/classes/META-INF/ejb-jar.xml
...
<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
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
N
M
Etudiants
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
Types de transaction
Transaction
avant
l’exécution
présente
aucune
Réaction
du conteneur
RequiresNew
présente
aucune
une nouvelle
une nouvelle
Mandatory
présente
aucune
est gardée
erreur
Type de
transaction
Required
est gardée
une nouvelle
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
JSP
SportManagement
JSP
Servlet
Servlet
sport
person
sportName
location
personName
sportForm
personForm
•
The forms are saved in the HTTP session
•
Under the name derived from the class !
139
Output of data (same for input)
sportForm
location
Struts
JSP
sportForm.setLocation("xxx")
<bean:write
name="sportForm"
property="location"/>
<html:text
name="location"/>
No direct connection !
140
Basic structure of struts
PersonManagement
JSP
2
JSP
Servlet
Servlet
sport
person
3
personName
personForm
SportManagement
sportName
location
1
sportForm
•
The forms are saved in the client session
•
Under the name derived from the class !
141
1 Librairies Struts: Action Form ( = java bean )
/**
* @struts.form 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) {
e.printStackTrace();
// trap exceptions that may occur in your servlet
// 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
144
<action-mappings>
Fichier auxiliaire: struts-config.xml
(généré par xDoclet)
<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>
<action-mappings>
145
Action Forms  CMP Beans
Main
personForm[]
Action forms
Course
Person[]
PersonForm
finder ou
getCollection
Recrée une collection et
copie ses éléments dans
l’autre collection
// code prochaine page
Person
CMP beans
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
SportManagement
PersonManagement
In/out
Action
sport
Input
job
jobName
jobName
sportName
location
location
location
personName
jobName
jobName
jobName
location
location
location
personName
personForm
Action
jobName
jobName
jobName
location
location
location
sportName
location
sportForm[ ]
jobForm[]
Pas supporté
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 )
/**
* @struts.form 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
http://localhost:8080/struts-documentation
http://ltiwww.epfl.ch/WebLang/references.html
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> &nbsp; &nbsp; &nbsp; name &nbsp; &nbsp;
<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> &nbsp;<bean:write name="item1" property="subName"/>
</table>
<td>
<table border="0" width="100%"<%=color[index1.intValue()%2]%>>
<td><bean:write name="item1" property="number"/>
</table>
<td>
<table border="0" width="100%" <%=color[index1.intValue()%2]%>>
<td><html:checkbox property='<%="thingN["+index1.intValue()+"].check"%>'/>
</table>
</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
JSP
State_1
state == 1
transition
from state 1
state = 2
sportName
location
JSP
State_2
state == 2
transition
from state 2
state = 1
165
WebLang use of the JSPs and servlets
sportName
location
JSP
FSM bean
JSP
FSM bean
personName
Where to start ? In the bean!
Same bean,
but different states
166
Finite State Machine in a Struts
page_0
0
not
confirmed
page_1
showBasket
1
confirmed
2
page_2
OK
Struts
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) ;
}
}
WebLang Module :
Finite State Machine
stateMachine {
state State_0 > supply;
state State_1 > supplyConfirmation;
// Pure Java code
switch (sessionState) {
case State_S:
sessionState = State_0;
break;
case State_0:
Pet pet = petHome.create( petForm.getName() );
sessionState = State_1;
break;
case State_1:
if (supplyConfirmation.getConfirmation())
sessionState = State_0;
}
}
168
169
WebLang Module : Forms (Java beans)
form SportForm {
package fmPack;
String sportName;
int location);
}
form PersonForm {
// sub-form
package fmPack;
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);
petForm.aaa ();
}
// display a button
// displays no button
171
Struts JSP
struts Supplier {
...
page supply {
petForm;
petForm.thingN[ ];
}
}
form PetForm {
package fp;
String name;
Thing thingN[];
}
form Thing {
package fp;
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
| readwrite
radio (aaa,bbb)
| combo (aaa,bbb)
| password
// last lines: one of each group, e.g. readwrite radio
175
Struts in WebLang
browseForm.petForm[ ]
(form)
browser
(JSP)
0
not
confirmed
showBasket
(JSP)
Action
Forms
showBasket
1
confirmed
orderregistered
(JSP)
2
OK
Struts
JSPs
basket.petFrom[ ]
(form)
Action Servlet
PetOrder
status = ordered
OrderItems*
(CMP+CMR)
CMP
bean
176
browseForm.petForm[ ]
(form)
Buying
browser
(JSP)
not
confirmed
showBasket
(JSP)
Administrator
0
showBasket
PetOrder
status = toBeChecked
OrderItems*
(CMP+CMR)
basket.petFrom[ ]
(form)
0
login
1
OrderForm.petForm[ ]
not  accept
(form)
confirmed
orderregistered
(JSP)
select
2
OK
areYouTheAdministrator
(JSP)
1
checkOrders
(JSP)
confirmed
Struts
PetOrder
status = ordered
OrderItems*
(CMP+CMR)
Struts
SendSupplierPO
Queue
Three tiers
(overview)
MDBean
file
Display
Business Layer
PetOrder
status = awaitInvoice
OrderItems*
(CMP+CMR)
Database
+ Dataflow
Business Layer
Display
177
Prints in WebLang
out
print
println
0
print
JSP
1
Struts
In the Struts, WebLang automatically defines a stream
named out, which contains methods
out.print(“xxx”);
out.println(“yyy”);
and
the text produced is automatically printed on the next JSP
178
Sub-FSMs
enter
application
display
ignore
start
timeout
application
enter
display
ignore
previous
next
start
timeout
enter
0
ignore
2
display_franc
s
1
display_euro
s
display
179
Sub-FSM
Struts A
State_S
(start)
Struts B
State_S
(start)
State_0
State_3
1st return
1st call
Goto B
Continue
State 0
State_R
(redirect)
State_1
Return
State_R
(redirect)
Goto B
Continue
Continue
State_3
2nd return
subsequent
calls
State_1
180
Page_1
Page_0
Groupe
Introduire
personnes/
groupes
EntrerGroupe
Personnes
Lister/former
groupes
Page_2
EntrerPersonne
Nom groupe
Quitter
Personnes
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
queue/topic
Sender
Clients
MDBean
Listener
SynReceiver
queue
topic
183
Types de canaux
Each message is recQueues
eived by a single client
Topics
Each client receives all
messages
Each client receives all Requires (only in input)
Durable messages, even if it is
subscription name
Topics temporarily disconusername, passwd
nected
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
http://ltiwww.epfl.ch/WebLang/JBossQueues.html
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
Serveur
Client
Object
inputchannel ch {
operation1()
operation2()
Listener
queue
topic
}
Needs C:\jboss-4.0.0\client\jbossall-client.jar
187
Envoyer des messante à une
queue ou un topic
Server
Client
Object
outputchannel ch {
ch.send(message)
proxy
}
queue
topic
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
mdbean MyMDB {
Pas de nom (à la diférence des autres)
package myPackage;
inputchannel
(queue, "MDBQueue") {
String s = ((TextMessage) msg).getText());
varName.send(msg);
}
// executed when a message arrives
outputchannel varName (queue, "B");
}
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);
}
}
Proxy d’un topic
194
(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)
Initialise le jeu game
Browser
Servlet
Java client
CMP beans
(nom de partie)
Java client
topic
Java client
Server
198
GUI
setUsername ()
getUsername ()
setPosition ()
setError ()
Java client
Message Listener
onMessage () {
GUI Listeners
actionPerformed() {
topic
}
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;
break;
case 2:
if (source != "done") return;
game.moveTerminated();
state = 1;
}
} 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
Application
(sur serveur)
stub
Serveur
remote object
== Java bean
204
Documentation sur la création des Web Services
Help > Help Contents >
Documentation
Bottom Up: Java bean  service
. . .
<wsdl:types>
<schema elementFormDefault="qualified"
<element name="grow">
<complexType>
<sequence>
<element name="p" type="impl:Person"/>
</sequence>
</complexType>
</element>
. . .
package web;
public class Test {
public Person grow(Person p){
p.setSize(p.getSize()+1);
return p;
}
}
WSDL
205
206
Web Services Description Language (WSDL)
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://web"
/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
<!--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="http://
</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
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
Recreates a collection and
copies one into the other
member by member
// code next page
Person
CMP beans
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
CMP bean: Customer
name
html: lottery
Start struts
Generated
automatically
struts: Lottery
- register(String)
- login()
- displayResults()
CMP bean: Token
WebLang
modules
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 the
@annotations introduced in Java 1.5
See the page WebLang about Hibernate
217
Annotations
/**
* @struts.form name="jeton"
(replace xDoclets)
*/
@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
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);
}
}
218
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
}
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();
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);
}
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
}
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
224
Using the objects of a Hibernate
relationship outside the transaction
Car
Owner
1
tx.begin();
...
owner = qt.getSingleResult();
owner.getCarN().size();
...
tx.commit();
for (Car c: owner.getCarN()) {
out.println(v.getName());
}
N
required to force the computation
(other functions may also be used)
otherwise not available
225
Both Action form and Hibernate bean
ejb3 MyCountry
extends strutsStateMachine.StateForm
{
package myPackage;
relations (Town=1:N);
String name;
int number;
}
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();
}
227
Transactions and display
No transaction
get from the DB
display,
let the user
modify the
data
Transaction
store into the DB
Transaction
Must reconnect the bean
to a transaction
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();
229
Handling a relationship
Car
Owner
tx.begin();
1
N
em.persist(owner);
for (Car c: cars) {
em.persist(c)
owner.add(c);
c.setCar(owner);
}
tx.commit();
// indispensable to introduce it into the DB
// because the reference is defined in table car
230
Merging a relationship
(could be done by using cascade)
Car
Owner
1
tx.begin();
N
c : Car
x : Owner
1
N
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
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
TownN tn = new TownN();
Finders
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"
}
}
235
FSM of the SQL beans
o = new Xxx()
Detached object
o.store()
pk=o.findPKXx()
o.findXx()
o.reload(pk)
o.set(o1)
o.add(o1)
o.set(null)
o.remove(o1)
o.store()
o.delete()
o.delete()
Attached object
Linked object
pk==0
pk!=0
o.reload(0)
o.set(null)
o.remove(o1)
o.set(o1)
o.add(o1)
o.reload()
o.reloadAll()
o.update()
o.updateAll()
o.reloadAll()
Attached + linked
+ connected object
pk!=0 rel!=0
o.delete()
o.storeAll()
o.deleteAll()
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
and connected:
The object is available in the database,
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
set, add
remove
storeAll
deleteAll
reloadAll
updateAll
Removes the data in the database,
not the memory, resets the object’s
primary key
Establishes connections between
the objects, the two directions of the
relationship are handled
Call all the objects bound by
a relationship (not recursively)
239
RMI Application
interface
Xxxx
interface
Xxxx
Xxxx
(stub)
Xxxx
(skeleton)
RemoteXxxx
Client
Server
240
RMI: inverse communication
(by transmitting the stub)
rmiregistry
Transfer
(stub)
1
Transfer
(skeleton)
2
MyRemote
(skeleton)
Client
3
MyRemote
(stub)
Server
241
RMI Module
rmi Test {
package rmis;
public void print (String s) {
System.out.println("X "+s);
}
}
jclient Client {
package rmis;
Test x;
RemoteTest y;
public void print (String s) {
try {
x.print(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// as Test corresponds to an rmi interface,
// x is automatically initialized
// y is not automatically initialized, the client
// must call new RemoteConnection(true)
242
Software Engineering
243
Application / implementation
Craig: (http://www.codegeneration.net/tiki-read_article.php?articleId=27)
Specifying software means components, interfaces, architectures, 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
Software application
A book has been lost
Check differences
Sort books
Reserve a book
(terminals, server, software)
245
browseForm.petForm[ ]
(form)
Buying
browser
(JSP)
not
confirmed
showBasket
(JSP)
Administrator
0
showBasket
PetOrder
status = toBeChecked
OrderItems*
(CMP+CMR)
basket.petFrom[ ]
(form)
0
login
1
OrderForm.petForm[ ]
not  accept
(form)
confirmed
orderregistered
(JSP)
select
2
OK
areYouTheAdministrator
(JSP)
1
checkOrders
(JSP)
confirmed
Struts
PetOrder
status = ordered
OrderItems*
(CMP+CMR)
Struts
SendSupplierPO
Queue
Three tiers
(overview)
MDBean
file
Display
Business Layer
PetOrder
status = awaitInvoice
OrderItems*
(CMP+CMR)
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
Java bean: LotteryData
- constantes générales
html: display_Manager
servlet: Manager
- tireJetons(int)
- tireJetons(int)
- client
cmpbean: Client
String nom
- afficheJetons()
1
N
html: display_GestionJeton
servlet: GestionJeton
sbean: AccesJetons
cmpbean: Jeton
- remplitJeton(int)
- remplitJeton(int)
- addJeton(Client, Jeton)
int numero
- afficheResultats()
- afficheResultats()
- listeResultats(Client)
int etat
html: display_Enregistrement
servlet: Enregistrement
- enregistre(String)
- enregistre(String)
- login(String)
- login(String)
attente
gagnant
perdant
html généré
Client
Serveur
249
Loterie
Java bean: LotteryData
html: display_Manager
- constantes générales
servlet: Manager
- tireJetons(int)
- client
- tireJetons(int)
- afficheJetons()
Browser
topic: testTopic
cmpbean: Client
String nom
class: LoterieGUI
listener:
1
N
(created with Visual Editor)
cmpbean: Jeton
int numero
int etat
Client
attente
gagnant
perdant
Serveur
250
Loterie
Java bean: LotteryData
html: display_Manager
- constantes générales
servlet: Manager
- tireJetons(int)
- client
- tireJetons(int)
- afficheJetons()
Browser
topic: testTopic
class: LoterieGUI
cmpbean: Client
String nom
- display: TextArea
- login: TextField
- tireJeton: TextField
listener:
1
display(String)
N
cmpbean: Jeton
sbean: ClientBean
invokeLater
class: Business
- login(String)
- login(String)
- tireJeton(int)
int numero
int etat
attente
gagnant
perdant
- tireJeton(int)
Client
Serveur