Java Edition Entreprise
Java Edition Entreprise
Java Edition Entreprise
Application Application
| ---HTTP--- |
Transport Transport
| |
Réseau Réseau
| |
| --réseau physique-- |
Les méthodes HTTP
Java EE (Java Enterprise Edition) est une norme proposée par la société Sun, portée
par un consortium de sociétés internationales, visant à définir un standard de
développement d'applications d'entreprises multi-niveaux, basées sur des composants.
On parle généralement de la plateforme JEE pour désigner les services offerts
(API), les composants et l’infrastructure d’exécution.
La plateforme JEE
La plateforme JEE comprend:
Les spécifications du serveur d'application, c'est-à-dire de l'environnement
d'exécution:
J2EE définit finement les rôles et les interfaces pour les applications ainsi que
l'environnement dans lequel elles seront exécutées. Ces recommandations permettent
ainsi à des entreprises tierces de développer des serveurs d'application conformes aux
spécifications ainsi définies, sans avoir à redévelopper les principaux services.
Les service, c'est-à-dire des extensions Java indépendantes permettant d'offrir
en standard un certain nombre de fonctionnalités. Ils pouvent être classés par
catégories :
Les services d'infrastructures : JDBC,JNDI…
Les services de communication : JavaMail,JAAS…
Les composants, on distingue habituellement deux familles de composants :
Les composants web : Servlet et JSP.
Les composants métier : EJB (Enterprise Java Beans). Il s'agit de
composants spécifiques chargés des traitements des données propres à un
secteur d'activité (on parle de logique métier ou de logique applicative) et de
l'interfaçage avec les bases de données.
Architecture Java EE
API Servlet
* Sevlet est masculin selon le grand dictionnaire terminologique, féminin selon le livre Servlets Java: guide des
programmeurs
Une servlet
Un programme java qui s'exécute côté serveur:
la portabilité, l'accès à toutes les API de java dont JDBC pour l'accès aux bases de
données, ...
Effectue les traitements et renvoie le résultat correspondant à la requête du
client. Elle agit selon le modèle requête/réponse.
Cette interaction peut être directe ou via un serveur http, ftp, etc
La principale utilisation actuelle est la génération de pages html dynamiques
utilisant le protocole http et donc un serveur web,
Mais n'importe quel protocole reposant sur le principe de requête/réponse peut
faire usage d'une servlet.
Une servlet peut être invoquée plusieurs fois en même temps pour répondre à
plusieurs requêtes simultanées.
La servlet se positionne dans une architecture Client/Serveur trois tiers dans le
tiers du milieu entre le client léger chargé de l'affichage et la source de données.
La version actuelle de la spécification servlet est 3.1 depuis Mai 2013.
Serveur d’application
Un serveur d'application permet de charger et d'exécuter les servlets
dans une JVM. C'est une extension du serveur web qui a ses limites:
Pas de contenu dynamique, Pas de sauvegarde de données sur le
serveur
Ce serveur d'application contient entre autre un moteur de servlets qui
se charge de manager les servlets qu'il contient: un conteneur
La notion de conteneur se retrouve dans de nombreuses technologies
– Servlet, Applet, MIDlet, Xlet, (*-let), EJB, …
Un conteneur est un composant logiciel système qui contrôle d’autres
composants, dits métier
– Tomcat est un exemple de conteneur
– Les servlets n’ont pas de méthode main(), ils sont contrôlés
par le conteneur Tomcat
– Les requêtes ne sont pas adressées aux servlets mais au
conteneur dans lequel ils sont déployés.
Pourquoi un conteneur ?
Un conteneur web est un moteur de servlet prend en charge l’instanciation et
le chargement de la servlet, gestion de son cycle de vie, passage des requêtes et
des réponses ... Un conteur web peut être intégré dans un serveur d'application
qui va contenir d'autre conteneur et éventuellement proposer d'autres services..
Pourquoi? Pour oublier le cours de « réseau » et faciliter la tâche du programmeur
Un conteneur fournit pour les Servlets
– Un support pour la communication
– La gestion du cycle de vie
– Un support pour le Multithreading
– Un support pour la sécurité
– Un support pour les JSP
Notion de module Web
Un servlet ne peut pas être déployé directement dans un conteneur, il doit faire
partie d’un module Web
Un module Web est un ensemble de librairies, de fichiers de configurations, de
code Java (bytecode des servlets…), …
Le module Web est l’unité de déploiement dans le conteneur
Le fonctionnement d’une servlet
Pour exécuter une servlet, il suffit de saisir une URL qui désigne la servlet dans un navigateur.
1. Le serveur reçoit la requête http qui nécessite une servlet de la part du navigateur
2. Si c'est la première sollicitation de la servlet, le serveur l'instancie. Les servlets sont stockées (sous
forme de fichier .class) dans un répertoire particulier du serveur. Ce répertoire dépend du serveur
d'application utilisé. La servlet reste en mémoire jusqu'à l'arrêt du serveur.
Remarque 2: La servlet en mémoire, peut être appelée par plusieurs threads lancés par le serveur pour
chaque requête. Ce principe de fonctionnement évite d'instancier un objet de type servlet à chaque
requête et permet de maintenir un ensemble de ressources actives tel qu'une connexion à une base de
données.
3. le serveur créé un objet qui représente la requête http et objet qui contiendra la réponse et les envoie à
la servlet
4. la servlet créé dynamiquement la réponse sous forme de page html transmise via un flux dans l'objet
contenant la réponse. La création de cette réponse utilise bien sûre la requête du client mais aussi un
ensemble de ressources incluses sur le serveur tels de que des fichiers (bean) ou des bases de données.
5. le serveur récupère l'objet réponse et envoie la page html au client.
Les outils pour développer
Il faut utiliser le Java Server Development Kit (JSDK) qui est une
extension du JDK.
Pour développer des servlets, le choix d’un des deux serveurs Apache
Tomcat ou Glassfish se justifie pleinement de part sa gratuité et sa
« légèreté »
L'API servlet
L'API servlets est une extension du jdk de base, regroupe dans des packages préfixés par
javax
Il en a deux:
javax.servlet : contient les classes pour développer des serlvets génériques indépendantes
d'un protocole
javax.servlet.http : contient les classes pour développer des servlets qui reposent sur le
protocole http utilisé par les serveurs web.
L'interface Servlet
Une servlet est une classe Java qui implémente l'interface javax.servlet.Servlet.
Cette interface définit 5 méthodes qui permettent au conteneur web de dialoguer avec la
servlet .
La requête et la réponse
Dans l’interface ServletRequest, plusieurs méthodes permettent d’obtenir des données sur
la requête du client :
L’interface ServletResponse
Servlets HTTP
src WebContent
Web.xml
Servlet en 4 étapes (2/4)
package ensat.cours.tp;
Ecrire servlet Clock et le mettre dans
import java.io.*;
import javax.servlet.http.*;
src
import javax.servlet.*;
reponse.setContentType("text/html");
PrintWriter out = reponse.getWriter();
out.println(doctype +
Code html"<html><head><title>"+title+"</title></head>"+
incorporé"<body><h1>Time On Server</h1>"+"<br>"+
new java.util.Date() +"</body></html>");
dans du out.close();
java }
}
Servlet en 4 étapes (3/4)
Créer un descripteur de déploiement et le
<?xml version="1.0" encoding="UTF-8"?> mettre dans WEB-INF
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-
app_2_4.xsd">
<display-name>WebModule1</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list> Servlet-name permet de lier <servlet
>et <servlet-mapping>
<servlet>
<servlet-name>The Clock</servlet-name>
<servlet-class>ensat.cours.tp.Clock</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>The Clock</servlet-name>
nom utilisé par
<url-pattern>/Serv1</url-pattern>
l’utilisateur dans sa
</servlet-mapping>
requête
Dans les projet web version 3 d’Eclipse, ce fichier est remplacé par des annotations
</web-app>
@WebServlet("/Controle")
Servlet en 4 étapes (4/4)
Démarrer le serveur (Tomcat)
Compiler la servlet
Lancer un navigateur et taper http://localhost:8080/Projet/Serv1
Premier TP
Le but est de créer une première application web:
Comment la créer, la déployer sur Tomcat (notre conteneur de servlet) et la tester?
Comme IDE, nous utiliserons Netbeans. En premier, il faut installer le plugins Java Web
Application.
Exemples de Servlet
Entêtes d’une requête GET
public class ShowRequestHeaders extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
IOException {
//...
out.println(doctype +
"<html>\n<head><title>" + title + "</title></head>\n" +
"<body>\n<h1>" + title + "</h1>\n" +
"<b>Request Method: </b>" + request.getMethod() + "<br />\n" +
"<b>Request URI: </b>" + request.getRequestURI() + "<br />\n" +
"<b>Request Protocol: </b>" + request.getProtocol() + "<br />)
while(headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
out.println("<tr><td>" + headerName + "</td>");
out.println("<td>" + request.getHeader(headerName) +"</td></tr>");
}
out.println("</table>\n</body></html>");
out.close();
}
}
Entêtes d’une requête GET (2) changer
Entêtes d’une requête POST
<form action="Serv2">
<table border="0">
<tr>
<td>Nom: </td><td><input type="text" name="nom"></td>
</tr>
<tr>
<td>Prénom:</td><td><input type="text" name="prenom"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="
Envoyer" </td>
</tr>
</table>
</form>
Traitement formulaire GET
Get http://localhost:8080/WebModule1/Serv2? nom=houda&prenom=Belmokadem
HTTP/1.1
host:localhost:8080
user-agent:Mozilla/4.0 GET
accept:image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
accept-language:fr
...
• response.sendRedirect(String url)
– Le code de status est alors 301
– L’attribut « Location » est également généré dans
l’entête de la réponse
Exemple sendError
public class LogServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
IOException {
String login = request.getParameter("param1") ;
String password = request.getParameter("param2") ;
if ((login == null) || (login.trim().equals(""))) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,“champs login
vide");
return;
}
if (checkUserAndPassword(login, password)) {
grantAccessTo(login);
} else {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, “accès refuser
au compte" + login);
}
}
}
Exemple sendRedirect
public class WrongDestination extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userAgent = request.getHeader("User-Agent");
if ((userAgent != null) &&(userAgent.contains("MSIE")) {
response.sendRedirect("http://home.netscape.com");
}
else {
response.sendRedirect("http://www.microsoft.com");
}
}
}
if ( ServletFileUpload.isMultipartContent(request) ) {
webContent
Que contient une JSP?
<body>
<% String visitor= request.getParameter(request.getParameter("name"));
if(visitor== null) visitor="World";%>
Hello, <%=visitor %>!
</body>
<body>
<jsp:useBean id="Bean" class="ensat.cours.HelloBean" />
<jsp:setProperty name="Bean" property="name" param="x"/>
Hello, <jsp:getProperty name="Bean" property="name"/>
</body>
Les conventions des balises
Quatre catégories:
Les actions : permettent de transférer le contrôle entre les pages, interagir avec
les composants JavaBeans côté serveur.
Les directives 1
Il en existe trois : taglib, page et include.
Elles sont toujours comprises entre les balises <%@ et %>, et hormis la directive
d'inclusion de page qui peut être placée n'importe où, elles sont à placer en tête de
page JSP.
1. Directive Taglib
<%@ taglib prefix=”lib" uri=”/TagLib.tld" %>
l’attribut uri précise où se trouve la librairie, l’attribut préfixe est unique pour chaque
librairie précise que le tags de cette librairie sera précédé par lib:
2. Directive page
<%@ page attribut1= “valeur1” attribut2= “valeur2” attribut3=“valeur3” …%>
L’attribut info: <%@ page info="the ensat homepage by h.bel" %> Le texte descriptif
fourni sera renvoyé par la méthode getServletInfo() de la servlet générée.
L’attribut language: : <%@ page language="java” %> définit le langage utilisé pour écrire
le code dans la JSP. La seule valeur autorisée actuellement est «java».
La directive include permet d'inclure un fichier dans le code source JSP. Le fichier
inclus peut être un fragment de code JSP, HTML ou Java. Le fichier est inclus dans
la JSP avant que celle-ci ne soit interprétée par le moteur de JSP.
Ce tag est particulièrement utile pour insérer un élément commun à plusieurs pages
tel qu'un en-tête ou un bas de page.
Si le fichier inclus est un fichier HTML, celui-ci ne doit pas contenir de tag
<HTML>, </HTML>, <BODY> ou </BODY> qui ferait double emploi avec ceux
présents dans le fichier JSP. Ceci impose d'écrire des fichiers HTML particuliers
uniquement pour être inclus dans les JSP : ils ne pourront pas être utilisés seuls.
Texte HTML
<h1>Blah</h1>
Passé au client. Réellement traduit en servlet par le code
out.print("<h1>Blah<h1>");
Commentaires HTML
<!-- Commentaire -->Pareil que les autres éléments HTML : passés au client
Commentaires JSP
<%-- Commentaires --%>Ne sont pas envoyés au client
Expressions
Format : <%= expression %>
Evaluée et insérée dans la sortie du servlet se traduit par
out.print(expression)
Scriptlets
Format : <% code %>
Inséré tel quel dans la méthode _jspService du servlet (appelée par
service)
Déclarations
Format : <%! code %>
Insérée telle quelle dans le corps de la classe servlet, en dehors de toute
méthode existante
Expressions JSP:
<%= valeur %>
Expressions JSP
Format
<%= Expression Java %>
Résultat
Expression évaluée, convertie en String, et placée dans la page HTML à la
place qu’elle occupe dans la JSP
L’expression est placée dans _jspService en paramètre du out.print()
Exemples
Heure courante : <%= new java.util.Date() %>
Hostname: <%= request.getRemoteHost() %>
Correspondance JSP/Servlet
JSP d’origine
Les spécifications des JSP définissent plusieurs objets utilisables dans le code dont
les plus utiles sont :
request
Instance de HttpServletRequest (1e argument de service/doGet)
response
Instance de HttpServletResponse (2e argument de service/doGet)
out
Intance de JspWriter (une version bufferisée de Writer) utilisée pour envoyer des
donnés sur la sortie vers le client
session
Instance de HttpSession associée à la requête (sauf si désactivée avec l’attribut
session de la directive de la page)
Scriptlets JSP:
Résultat
Code inséré tel quel dans _jspService()
Exemple
<%
String queryData = request.getQueryString();
out.println("Attached GET data: " + queryData);
%>
<% response.setContentType("text/plain"); %>
Scriptlets JSP: Exemple
On veut permettre à l’utilisateur de choisir la couleur de fond de la page HTML
<!DOCTYPE …>
<html>
<head>
<title>Color Testing</titl>
</head>
<%
String bgColor = request.getParameter("bgColor");
if ((bgColor == null)||(bgColor.trim().equals(""))){
bgColor = "WHITE";
}
%>
<body bgcolor="<%= bgColor %>">
<h2 align="CENTER">Testing a Background of "<%= bgColor %>".</h2>
</body></html>
Utilisation des scriptlets pour
créer des parties conditionnelles
Postulat
– Les scriplets sont insérés tels quels dans le servlet
– Pas besoin d’avoir des expressions Java complètes
– Cependant, les expressions complètes sont la plupart du temps plus claires et
faciles à maintenir
Exemple
<% if (Math.random() < 0.5) { %>
Vous avez <b>gagné</b> !
<% } else { %>
Vous avez <b>perdu</b> !
<% } %>
Code du servlet résultant de la traduction
if (Math.random() < 0.5) {
out.println("Vous avez <b>gagné</b> !");
} else {
out.println("Vous avez <b>perdu</b> !");}
Déclaration JSP
<%! Code %>
Déclarations JSP
Format
<%! Java Code %>
Résultat
Insérées telle quelle dans la définition de la classe du servlet, en
dehors de toute méthode existante
Exemples
<%! private int someField = 5; %>
<%! private void someMethod(...) {...} %>
Remarque de conception
Les attributs sont clairement utiles. Pour les méthodes, il est la
plupart du temps préférable de les définir dans une classe Java
Séparée
Correspondance JSP/Servlet
JSP d’origine
<h1>Some Heading</h1>
<%!
private String randomHeading() {
return("<h2>" + Math.random() + "</h2>");
}
%>
<%= randomHeading() %>
2. jspDestroy()
La méthode jspDestroy est appelé par le conteneur au moment où la ressource est sur
le point d’être détruite.
Déclarations JSP et variables prédéfinies
Rq1: Problème
– Les variables prédéfines (request, response, out, session, etc.)
sont locales à la méthode _jspService.
Ainsi, elles ne sont pas disponibles pour les méthodes définies par
des déclarations JSP et les méthodes des classes externes.
– Que peut-on faire ?
Solution : les passer en paramètres. Ex :
<%!
private void someMethod(HttpSession s) {
doSomethingWith(s);
}
%>
<% someMethod(session); %>
Rq 2 : println de JSPWriter lance une IOException
– Utiliser “throws IOException” pour les méthodes qui utilisent println
Intégration
des servlets et des JSP :
Application du design pattern
Model-View-Controller (MVC)
Pourquoi combiner Servlets & JSP?
Classiquement : utilisation des JSP pour faciliter le
développement et la maintenance du contenu HTML
import javax.servlet.http.HttpServletResponse;
import ensat.cours.logiquemetier.Promo;
public class SelectPromo extends HttpServlet {
public void doGet(HttpServletRequest re, HttpServletResponse
pe)
throws IOException, ServletException{
...
String param = re.getParameter("promo");
...
}
}
MVC : étape 3
3. La servlet controller interroge le model sur « info3 »
4. Le model retourne au controller le résultat correspondant
Model: une classe Java
<body>
<%
List<String> l = (List<String>) request.getAttribute("liste");
System.out.println(l==null);
Iterator i = l.iterator();
while(i.hasNext()){
out.println("<br>" + i.next());
}
%>
</body>
Cookies et suivi de session
TP Cookies
Introduction
L'API javax.servlet.http.Cookie
Travail à réaliser
Introduction
Un cookie est une information envoyée par un serveur web à un navigateur et
sauvegardée par celui-ci sur le disque de sa machine
Le navigateur retourne cette information (inchangée) lorsqu'il visite de nouveau le même
site.
Ayant lu cette information, le serveur peut identifier le client et lui fournir un certain
nombre de facilités :
achat en ligne
authentification
personnalisation de portail
diriger les recherches d'un moteur
Pas de menace sécuritaire
Un cookie est défini par son nom auquel est associée une valeur.
Il est possible d'y ajouter certains attributs
Introduction
Solutions
java.util.Enumeration HttpSession.getAttributeNames()
retourne tous les noms d'attributs associés à la session
L’identifiant est stocké dans un cookie appelé JSESSIONID => seul l’identifiant
de session est envoyé au client.
Relation indirecte
Architecture Web JEE: model1
(pas MVC)
JavaBeans ?
Les JavaBeans sont des classes Java (POJO) qui suivent
certaines conventions :
– Doivent avoir un constructeur vide (zero argument)
• On peut satisfaire cette contrainte soit en définissant explicitement un tel
constructeur, soit en ne spécifiant aucun constructeur
– Ne doivent pas avoir d’attributs publics
• Une bonne pratique réutilisable par ailleurs…
– La valeur des attributs doit être manipulée à travers des méthodes
getXxx et setXxx
• Si une classe possède une méthode getTitle qui retourne une String, on dit que
le bean possède une propriété String nommée title
• Les propriétés Boolean utilisent isXxx à la place de getXxx
But:
– Permettre l’instanciation de classes Java sans programmation Java
explicite (syntaxe compatible XML)
Remarques:
– Interpretation simple :
<jsp:useBean id="book1" class="coreservlets.Book" />
peut être vu comme équivalent au scriptlet :
<% coreservlets.Book book1 = new coreservlets.Book(); %>
But
– Permettre d’accéder propriétés d’un bean (i.e., appel de
méthodes getXxx) sans programmation Java explicite
Remarques
– <jsp:getProperty name="book1" property="title" />
<OL>
<LI>Initial value (from jsp:getProperty):
<I><jsp:getProperty name=“testBean" property="message" /></I>
<LI>Initial value (from JSP expression):
<I><%= testBean.getMessage() %></I>
<jsp:setProperty name=“testBean" property="message" value=“Exemple d’un autre
message" />
<LI> Value after setting property with jsp:setProperty:
<I><jsp:getProperty name=“testBean" property="message" /></I>
<%
try {
double salaire = Double.parseDouble(request.getParameter(“champs3"));
} catch(NumberFormatException nfe) {}
%>
<jsp:useBean id = "utilisateur" class = "Personne" />
...
<jsp:setProperty name
= "utilisateur" property = "prénom" param = "prénom" />
<jsp:useBean id = "utilisateur" class = "Personne" />
...
<jsp:setProperty name = "utilisateur" property = "prénom" />
jsp:setProperty (cas3) : associer
toutes les propriétés aux paramètres
Utilisation de "*" pour la valeur de l’attribut property de jsp:setProperty
– On indique que la valeur doit provenir des paramètres de requête qui
correspondent aux noms des propriétés
– Un conversion automatique de type est également opérée
– Particulièrement pratique pour réaliser des « Beans formulaires » --
objets dont les propriétés sont remplies par les données d’un formulaire
– Ce processus peut même être décomposé entre différents formulaires,
chaque soumission remplissant une partie de l’objet
request
– <jsp:useBean id="..." type="..." scope="request" />
session
– <jsp:useBean id="..." type="..." scope="session" />
application
– <jsp:useBean id="..." type="..." scope="application" />
page
– <jsp:useBean id="..." type="..." scope="page" />
ou juste
<jsp:useBean id="..." type="..." />
– Ce scope n’est pas utilisé dans MVC
Exemple : Partage de données sur requête
Servlet
ValueObject value = new ValueObject(...);
request.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher("SomePage.jsp");
dispatcher.forward(request, response);
JSP 1.2
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="request" />
<jsp:getProperty name="key" property="someProperty" />
JSP 2.0
${key.someProperty}
Partage de données sur requête :
exemple simple
Servlet
Customer myCustomer = new
Customer(request.getParameter("customerID"));
request.setAttribute("customer", myCustomer);
RequestDispatcher dispatcher =
request.getRequestDispatcher("SomePage.jsp");
dispatcher.forward(request, response);
JSP 1.2
<jsp:useBean id="customer" type="somePackage.Customer"
scope="request" />
<jsp:getProperty name="customer" property="firstName"/>
JSP 2.0
${customer.firstName}
Partage de données sur session
Servlet
ValueObject value = new ValueObject(...);
HttpSession session = request.getSession();
session.setAttribute("key", value);
RequestDispatcher dispatcher =
request.getRequestDispatcher("SomePage.jsp");
dispatcher.forward(request, response);
JSP 1.2
<jsp:useBean id="key" type="somePackage.ValueObject"
scope="session" />
<jsp:getProperty name="key" property="someProperty" />
JSP 2.0
${key.someProperty}