Introduction au J2EE – Java 2 Enterprise Edition
Répartition Client-Serveur
Traitement coté client (User Agent)
extériorisation de l ’information
formats visualisables par le client
interactivité non lié au réseau
Interactivité requierant le serveur (RIA + Bayeux protocol)
Traitement coté serveur
serveur applicatif
conserve les traitements en interne (business logic)
adapté le document retourné au capacité du visualisateur
prise en compte des champs accept: communiqués par le client
charge le serveur
Le Scripting Serveur
Utilisation
Traitement des formulaires par le serveur
Génération de pages HTML à la volée
requête sur des bases de données, …
Les Techniques
Script générant du HTML
CGI : Common Gateway Interface, Fast-CGI
NSAPI, ISAPI, Servlets
Script embarqué dans des pages HTML
SSI : Server Side Include
SSS : Server Side Script
Active Server Pages (MicroSoft), SSJ (NS), JSP (Sun), PHP,
EJS (Express) ...
…
RDBMS
Application
tables
Web Browser Web Server EJB Server
HTML
HTTP
Session
Bean Bean
Entity
Bean
Entity
Bean
RMI
JDBC/SQL
XA
Servlet Servlet RMI
RDBMS
Application
tables
Web Browser Web Server EJB Server
HTML
HTTP
Session
Bean Bean
Entity
Bean
Entity
Bean
RMI
JDBC/SQL
XA
Servlet Servlet
RMI
State replication for failover
JavaEE et EMB (Enterprise Media Beans)
Web Server EJB Server
HTML/SMIL
HTTP
Enterprise
Media Beans
RMI/SSL
IIOP/SSL
Servlet,
Filter,
JSP, JSF
Servlet,
Filter, Enterprise
Beans Beans
RDBMS/ERP
DataSource
JDBC
JCA
web cam site
blah blah
blah blah
blah blah
blah blah
blah blah
MPEG,…
RTSP
xHTML/SMIL
HTTP
MPEG,…
RTSP
Streaming
Server
Media
Plugin
Media
Metadata Plugin
Repository
Stream
Repository
Web Browser
+ JMF, WMP,
RealOne
…
J2ME
Mobile Media
API (JSR135)
Web application
Partie « présentation » d’une application JavaEE
Servlet
Filter
JSP (Java Server Page)
JSTL (Java Server Tag Library)
JSF (Java Server Face)
+
Classes, bibliothèques (Jar File), …
Ressources (Document statiques, Images, Messages internationalisés (i18n), Propriétés …)
Packaging d’une application Web en JavaEE (Web Component)
Web Component
Une application Web (*.html, *.jsp, servlets, …) packagée dans un .jar
(.war) et est paramêtrée dans le fichier WEB-INF/web.xml
L’application est installée dans le répertoire webapps du serveur web JavaEE
Structure d’une Web Application Archive (.war)
*.html, *.png, *.jsp, …, applets.jar, midlets.jar
WEB-INF/web.xml
Fichier de déploiement
Paramêtrage des servlets, types MIME additionnels, …
WEB-INF/classes/
.class des servlets et des classes (JavaBean, …) associées
ressources additionnelles (localstring.properties, …)
WEB-INF/lib/
.jar additionnels provenant de tierce parties (comme des drivers JDBC,
TagLib (jsf, …), …
WEB-INF/tlds/
.tld décrivant les TagLibs
Le fichier WEB-INF/web.xml
Fichier de déploiement de l’application
Correspondance URI -> classes Servlets
Valeurs d’initialisation des Servlets
Valeurs d’environnement
Ressources
Références vers EB Home, DataSource, Mail Session, …
Types MIME supplémentaires
text/vnd.wap.wml, text/vnd.sun.j2me.app-descriptor, …
Contraintes de sécurité
…
EAR : ecom.ear
application
.xml
Rappel
Packaging d’une application JavaEE complète
EJB-JAR : ecom.jar
.class
.class
.class
ecom
.xml
Web App : ecomadmin.war
.htm
(servlet)
.class .jsp
web
.xml .png
applets
.jar
.tld
Web App : ecomcustomer.war
.htm
(servlet)
.class .jsp
web
.xml .png
midlets
.jar
.tld
Java application :
ecomshell.jar
.class
.class
.class
.mf
Servlet et Filter
Les Servlets
Servlets
Scripts serveur écrit en Java
Servlets de Base : FileServlet, CGIServlet, …
HttpServlet, SIPServlet, …
Exécution dans un espace isolé (Web Application)
javax.servlet
InputStream ServletInputStream
OutputStream ServletOutputStream
Object Servlet
Exception ServletException
GenericServlet
ServletConfig
ServletContext
ServletRequest
ServletResponse
SingleThreadModel
java.io
java.lang
javax.servlet.http
HttpServletContext
HttpServletRequest
HttpServletResponse
HttpServlet
HttpSession
HttpSessionBindingListener
Cookie
HttpUtils
Serializable
EventListener
Filter
L’API Servlet
javax.servlet et javax.servlet.http
Exemple de Servlet
Hello World !
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String pname = req.getParameter("name"); // Get a parameter
if(pname==null) pname="World !";
res.setContentType("text/html"); // Set the Content-Type header
PrintWriter out = res.getWriter(); // Get the output
out.println("");
out.println("Hello, " + pname + "");
out.println("");
out.println("Hello, " + pname);
out.println("");
out.flush();
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException { doGet(req, res); }
}
Servlets
Cycle de Vie (i)
Web Container
Servlet .class Chargement
Remarque :
spécifié lors du déploiement
Web Container
Servlet
Client
Client
Traitement de
1 à N requêtes
service()
Remarque :
l ’état est conservé
entre les requêtes
Web Container
Servlet
Initialisation
init()
Remarque :
spécifié lors
du déploiement
Web Container
Servlet
Destruction
destroy()
Remarque :
Shutdown du serveur, ...
La Requête
L ’exploration du serveur
public class ServerSnoop extends GenericServlet {
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");PrintWriter out = res.getWriter();
out.println("Server: getServletContext().getServerInfo(): " +
this.getServletContext().getServerInfo());
Enumeration atts=this.getServletContext().getAttributeNames();
while(atts.hasMoreElements()){ // informations supplémentaires du constructeur
String att= (String)atts.nextElement();
out.println("Server: getServletContext().getAttribute(\""+att+"\"): " +
this.getServletContext().getAttribute(att);
}
out.println("Server: req.getServerName(): " + req.getServerName());
out.println("Server: req.getServerPort(): " + req.getServerPort());
} }
La Requête
L ’exploration du client
public class ClientSnoop extends GenericServlet {
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");PrintWriter out = res.getWriter();
out.println("Client: req.getRemoteHost(): " + req.getRemoteHost ());
out.println("req.getRemoteAddr(): " + req.getRemoteAddr ());
} }
La Requête
La récupération des paramêtres (POST ou GET)
public class ParameterSnoop extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException { doGet(req,res); }
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println("Query String:"); out.println(req.getQueryString()); out.println();
out.println("Request Parameters:");
Enumeration pnames = req.getParameterNames();
while (pnames .hasMoreElements()) {
String name = (String) pnames.nextElement();
String values[] = req.getParameterValues(name);
if (values != null) {
for (int i = 0; i < values.length; i++) {
out.println(name + " (" + i + "): " + values[i]);
}
} } } }
La Requête
La recupération des entêtes
public class HeaderSnoop extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println("Request Headers:");
out.println();
Enumeration enum = req.getHeaderNames();
while (enum.hasMoreElements()) {
String name = (String) enum.nextElement();
String value = req.getHeader(name);
if (value != null) {
out.println(name + ": " + value);
} } } }
La Requête
La recupération des Cookies
public class CookiesSnoop extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain"); PrintWriter out = res.getWriter();
out.println("Cookies:");
javax.servlet.http.Cookie[] cookies = req.getCookies();
for (int c=0;c<cookies.length;c++) {
out.print("Name:" + cookies[c].getName());
out.print("Value:" + cookies[c].getValue());
out.print("Domain:" + cookies[c].getDomain());
out.print("Path:" + cookies[c].getPath());
out.print("Secure:" + cookies[c].getSecure());
out.print("Version:" + cookies[c].getVersion());
out.print("MaxAge:" + cookies[c].getMaxAge());
out.println("Comment :" + cookies[c].getComment());
} } } }
La Requête
La récupération du flot d ’entrée
public class InputStreamSnoop extends GenericServlet {
public void service( ServletRequest req, ServletResponse res)
throws ServletException, IOException {
String contenttype=req.getContentType ();
int contentlength=req.getContentLength ();
2 flots de données possibles
java.io.BufferedReader in= req.getReader();
...
javax.servlet.ServletInputStream in= req.getInputStream();
…
Utilisation exclusive sinon IllegalStateException
Utilisation
décodage d’un corps en multipart/data
La Réponse
La réponse simple
public class Hello extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("");
out.println("Hello World");
out.println("");
out.println("Hello World");
out.println("");
} }
La Réponse
Maintien de la connexion (KeepAlive)
public class KeepAliveHello extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
// Set up a PrintStream built around a special output stream
ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024);
PrintWriter out = new PrintWriter(bytes, true); // true forces flushing
out.println("");
out.println("Hello World");
out.println("");
out.println("Hello World");
out.println("");
res.setContentLength(bytes.size()); // Set the content length
bytes.writeTo(res.getOutputStream()); // Send the buffer
} }
La Réponse
Les codes d ’état et la journalisation
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
...
try {//
...
} catch (FileNotFoundException e) {
// utilise le journal de GenericServlet
this.log("Could not find file: " + e.getMessage());
// envoi du code 404
res.sendError(HttpServletResponse.SC_NOT_FOUND);
} catch (IOException e) {
// utilise le journal de ServletContext
this.getServletContext().log(e, "Problem sending file");
// envoi du code 500
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.toString());
}
}
La Réponse
L’ajout d ’entête
public class ClientPull extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res )
throws ServletException, IOException {
res.setContentType("text/plain"); PrintWriter out = res.getWriter();
res.setHeader("Refresh", "10");
out.println(new Date().toString());
} }
La Session javax.servlet.http.HttpSession
Le suivi de session
Le serveur maintient une session de 2 manières :
Cookie (Name: SESSIONID Value: To1010mC8601021835741167At)
les cookies peuvent être déactivés sur le navigateur
Réécriture des URLs
Ouverture/récupération d’une session
javax.servlet.http.HttpSession session = req.getSession(false);
// la session est récupérée ou null si elle n’existait pas déjà
javax.servlet.http.HttpSession session = req.getSession(true);
// la session est récupérée ou ouverte si elle n’existait pas déjà
Invalidation d’une session
javax.servlet.http.HttpSession session = req.getSession(false);
session.invalidate(); // la session est invalidée (i.e. fermée)
La Session javax.servlet.http.HttpSession
Information sur la session
javax.servlet.http.HttpSession session = req.getSession(false);
L ’identifiant
String sessionid= session.getId(); // par exemple: To1010mC8601021835741167At
La date de création long datecreation= session.getCreationTime(); // nb de ms depuis 1/1/1970:00:00
La date du dernier accès
long datelastaccess= session.getLastAccessedTime();
Exemple
HttpSession session = req.getSession(true);
if(session.getLastAccessedTime() - session.getCreationTime() > 5*60*1000 ) {
session.invalidate();
}
La Session javax.servlet.http.HttpSession
Liaison d ’objets à une session
javax.servlet.http.HttpSession session = req.getSession(true);
Ajout/remplacement d ’une valeur void HttpSession.setAttribute(String name, Object value)
Suppression d ’une valeur
void HttpSession.removeAttribute(String name)
Récupération des valeurs/d ’une valeur
Enumeration HttpSession.getAttributeNames()
Object HttpSession.getAttribute(String name)
La Session javax.servlet.http.HttpSession
Exemple de liaison d ’objets
import mycybermarket.Cart; …
public void doGet(HttpServletRequest req, HttpServletResponse res) … {
Cart cart;
HttpSession session = req.getSession(true);
if((cart=(Cart)session.getAttribute("CART"))!=null) {
cart=CartFactory.create(); // new Cart( ... ); ou =cartHome.create();
session.setAttribute("CART",cart);
} ...
...
if(action.equals("exit") {
cart.releaseProducts();
session.removeAttribute("CART");
}
...
La Session
Observateurs sur la session
Motivations
réagir face à des événements intervenants dans la/les sessions
4 interfaces Listeners
HttpSessionActivationListener la session peut être passivée puis réactivée
HttpSessionListener
changement sur la liste des sessions actives de l'application Web.
HttpSessionAttributeListener
changement sur les attributs d’une des sessions de l’application Web.
HttpSessionBindingListener
un objet peut être notifié de sa liaison/rupture à un session
La Session
Exemple de Observateur de Liaison
class CartBindingListener implements HttpSessionBindingListener {
Cart cart=null;
public CartBindingListener( ... ) { this.cart = new Cart( ... ); }
public void valueBound(HttpSessionBindingEvent event) {}
public void valueUnbound(HttpSessionBindingEvent event)
{ cart.releaseProducts();}
public void doGet(HttpServletRequest req, HttpServletResponse res) {
CartBindingListener cart;
HttpSession session = req.getSession(true);
CartBindingListener cart=(Cart)session.getValue("CART");
if(cart==null) { cart=new CartBindingListener( ... );
session.setAttribute("CART",cart); // valueBound est invoqué sur l ’objet lié
} …
session.removeAttribute ("CART"); // valueUnbound est invoqué sur l ’objet lié
Accès à des ressources de l'application JavaEE
Enterprise JavaBeans
DataSources (Bases de données)
JMS (Queues/Topics)
…
Accès aux Entreprise Beans
WEB-INF/web.xml
ejb/Cart
Session
myapp.beans.CartHome
myapp.beans.Cart
myapp.jar#Cart
ejb/CartLocal
Session
myapp.beans.CartLocalHome
myapp.beans.CartLocal
myapp.jar#Cart
Accès aux Entreprise Beans
Code
Context ctx = new InitialContext
// start transactions from client: get UserTransaction
UserTransaction utx= (UserTransaction)
initialContext.lookup("java:comp/UserTransaction");
// Connecting to CartLocalHome thru JNDI
ICartLocalHome cartLocalHome =
ctx.lookup("java:comp/env/ejb/CartLocal ");
ICartLocal cartLocal = cartLocalHome.create(SessionId);
Accès aux Entreprise Beans
via les annotations
@ManagedBean
public class CartServlet extends HttpServlet {
@EJB(mappedName = "LocalCart")
private ICart cart;
void doGet(...) {
...
cart.add(productId,qte, …) ;
….
}
Request Dispatch
Redirige la traitement de la requête vers une autre servlet ou JSP
Utilisé pour le MVC (Controleur)
Exemple
public class ForwardServlet extends HttpServlet {
public void doGet (HttpServletRequest request,
HttpServletResponse response) {
// Set the attribute and forward to hello.jsp
request.setAttribute ("action", "hello");
ServletContext context=getServletConfig().getServletContext().
context.getRequestDispatcher("/hello.jsp").forward(request, response);
}
}
Filtre (Filter)
Traitement s’interposant entre le client et la ressource
(Servlet, JSP, fichier) requise
en pré-traitement et/ou et post-Traitement
Chaînage de filtres (selon l’ordre de déclaration dans web.xml)
Exemple de filtres
Authentification
Conversion (Image), Transformation (XSLT, FOP)
Chiffrage/Compression (Image,Données gzip)
Audit/Journalisation, Caching
Load balancing/Redirection (304Filter)
API
javax.servlet.Filter
init(FilterConfig config)
doFilter(request,response,chain) { … chain.doFilter(request,response); … }
destroy()
Déploiement dans le descripteur web.xml
Exemple de Filtre
public class TraceFilter implements javax.servlet.Filter {
private String separator;
private FilterConfig filterConfig
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig= filterConfig;
this.separator = filterConfig.getInitParameter("fieldseparator");
}
public void doFilter(ServletRequest req,ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hreq = (HttpServletRequest)req;
long startTime = System.currentTimeMillis();
chain.doFilter(req, res);
long stopTime = System.currentTimeMillis();
log(hreq.getRemoteAddr()
+ separator + hreq.getServletPath() + separator + (stopTime-startTime));
}
private void log(String msg){ filterConfig.getServletContext().log(msg); }
}
Servlet 3.0 (JSR 315)
Servlet asynchrone
Support pour Comet et WebSockets
Annotations
@WebServlet, @WebFilter, @WebListener
@ServletSecurity, @MultipartConfig
Fragment web.xml
Support Multipart
...
Exemple de Servlet par Annotation
@WebServlet(name=”MyHelloServlet”,
urlPatterns={"/hello*", "/hi"},
initParams={ @InitParam(name="fr", value="Bonjour"),
@InitParam(name="es", value="Hola") }),
asyncSupported=true
)
public class HelloServlet extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse res) {
AsyncContext aCtx = req.startAsync(req, res);
….
}
}
JSR 224 JAX-WS
API pour les Web Services
Exemple
@WebService
public class Hello {
@WebMethod
public String sayHello(String name) { return "Hello "+ name; }
}
public class HelloAppClient {
@WebServiceRef(wsdlLocation = " ")
private static HelloService service;
public static void main(String[] args) {
Hello.endpoint.Hello port = service.getHelloPort();
System.out.println(port.sayHello("world"));
}}
Proxy client généré par wsimport -p hello
JSR-311
Java API for RESTful Web Services
Motivations
API Java for RESTful Services
Java 1.5 Annotation for POJO : @Path, @GET, @POST, …
Exemple
@Path("/library")
@Produces{"application/json"}
public class Library {
@GET @Path("/book")
public String getBooks() {...}
@GET @Path("/book/{isbn}")
public String getBook(@PathParm("isbn") String id) { … }
@POST @Path("/book/{isbn}")
@Consumes("application/x-www-form-urlencoded")
public String getBook(FormURLEncodedProperties formData) { … }
@POST @Path("/book/{isbn}")
@Consumes("multipart/related")
public String getBookMulti(MimeMultipart mimeMultipartData) { … }
@PUT @Path("/book/{isbn}")
public void addBook(@PathParam("isbn") String id, @QueryParam("name") String name) {...}
@DELETE @Path("/book/{id}")
public void removeBook(@PathParam("id") String id {...}
}
JSP & JSTL
JSP (Java Server Page)
Server Side Script
Insertion de SSS (syntaxe Java) dans les pages HTML
Avantage par rapport aux servlets
Ecriture moins verbeuse Orientée Web Designer
Insérable par des outils auteurs dans le code de pages
HTML
Extensible grâce aux JSTL
Spécification
JSR-52
JSR-152 JavaServer Pages 2.0 Specification
Implémentations
J2EESDK et Jakarta JASPER/TomCat
Insertion des scripts
Directives
< "java.util.*" %>
< "c" uri="WEB-INF/tld/core.tld" %>
Éléments de script
Scriplets <% code java %>
Déclarations <%! Déclarations %>
Expressions <%= expression %>
TagLib
Exemple de traitement d ’un
formulaire
Hello
<%
String pname; // déclaration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
%>
Mister <%=pname%>
<% } // fin du else %>
Scriptlet
(source Java)
Expression (EL)
Exemple de traitement d’un formulaire
<%@ method = "doPost" %>
Hello
<%
String pname; // déclaration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
%>
Mister <%=pname%>
<% } // fin du else %>
Directives
<% varname="value" %>
content-type, import,
extends, implements,
method, language
JSP : Exemple avec une session
JSP listant un « caddie » virtuel
<%
cart.processRequest(request);
%>
You have the following items in your cart:
<% String[] items = cart.getItems();
for (int i=0; i<items.length; i++) { %>
<% } %>
<%@ include file ="catalog.html" %>
Didier Donsez, 1995-2009, Dev. Web en JavaEE
JSP
package mycybermarket;
import javax.servlet.http.*; import java.util.Vector; import java.util.Enumeration;
public class MyCart {
Vector v = new Vector(); String submit = null; String item = null;
private void addItem(String name) { v.addElement(name); }
private void removeItem(String name) { v.removeElement(name); }
public void setItem(String name) { item = name; }
public void setSubmit(String s) { submit = s; }
public String[] getItems() { String[] s = new String[v.size()]; v.copyInto(s); return s; }
public void processRequest(HttpServletRequest request) {
// null value for submit - user hit enter instead of clicking on "add" or "remove"
if (submit == null) addItem(item);
if (submit.equals("add")) addItem(item);
else if (submit.equals("remove")) removeItem(item);
reset(); // reset at the end of the request
}
private void reset() { submit = null; item = null; }
}
Génération des JSP
Compilation des JSP en classes Java
génération et compilation d ’une classe étendant HttpJspBas à la première invocation. e
Au runtime
la servlet JspServlet invoque le compilateur Jasper puis charge et exécute la méthode _jspService de la classe
HttpJspBase générée
Avant déploiement
Les JSP peuvent être aussi générées avant le déploiement (tâche )
JSP - Exemple de Génération
Parsing du document .jsp par JspServlet
Hello
<%
String pname; // déclaration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
%>
Mister <%=pname%>
<% } // fin du else %>
_jspx_html_data[0]
_jspx_html_data[1]
_jspx_html_data[2]
JSP - Exemple de Génération
chargement des fragments du document
public class jsp_0005chello_0002ejsphello_jsp_1 extends HttpJspBase {
static char[][] _jspx_html_data = null;
public jsp_0005chello_0002ejsphello_jsp_1( ) {
}
private static boolean _jspx_inited = false;
public final void _jspx_init() throws JspException {
ObjectInputStream oin = null;
int numStrings = 0;
try {
FileInputStream fin = new FileInputStream
("work\\%3A8080%2Fdemo\\C_0003a.test.jsphello.dat");
oin = new ObjectInputStream(fin);
_jspx_html_data = (char[][]) oin.readObject();
} catch (Exception ex) {
throw new JspException("Unable to open data file");
} finally {
if (oin != null)
try { oin.close(); } catch (IOException ignore) { }
}
}
JSP - Exemple de Génération la méthode _jspService (partie 1)
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
JspFactory _jspxFactory = null;PageContext pageContext = null;
HttpSession session = null; ServletContext application = null;
ServletConfig config = null; JspWriter out = null;
Object page = this; String _value = null;
try {
if (_jspx_inited == false) { _jspx_init(); _jspx_inited = true; }
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext
(this, request, response,"", true, 8192, true);
// objets implicites
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
// …
JSP - Exemple de Génération la méthode _jspService (partie 2)
// …suite de la méthode jspService
out.print(_jspx_html_data[0]);
// begin [file="C:\\test\\jsp\\hello.jsp";from=(4,2);to=(8,0)]
String pname; // d\u00e9claration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
// end
out.print(_jspx_html_data[1]);
// begin [file="C:\\ test \\jsp\\hello.jsp";from=(9,10);to=(9,15)]
out.print(pname);
// end
out.print(_jspx_html_data[2]);
// begin [file="C:\\ test \\jsp\\hello.jsp";from=(10,2);to=(10,5)]
} // fin du else
// end
out.print(_jspx_html_data[3]);
} catch (Throwable t) {
if (out.getBufferSize() != 0) out.clear();
throw new JspException("Unknown exception: ", t);
} finally { out.flush(); _jspxFactory.releasePageContext(pageContext);
}
}
}
JSTL
Java Server Tag Library
Motivations
Extension des JSP par des tiers
Développement modulaire
Développement sans Java (pour Web Designer)
Principes
Le document contient des éléments (tag) supplémentaires
Le générateur JSP appelle des classes tiers lors de la transformation qui implantent Tag, IterationTag ou
BodyTag.
JSTL usuels
JSTL
Usage
Directive
<%@ taglib uri="/WEB-INF/tlds/my-taglib.tld" prefix="my" %>
Invocation
some enclosed text here
Déploiement
WEB-INF/tlds/my-taglib.tld
Déclaration des classes implémentant la Tag Lib
WEB-INF/lib/my-taglib.jar
Jar file contenant les classes d’implémentation
TagLib usuels
Une liste non exhaustive …
jsp (action standard)
c (core)
fmt (formattage et internationalisation)
xml (xml, xpath et xslt)
sql (sql)
jsf/core, jsf/html, …
logic (Jakarta Struts)
tags (TagLib)
à déployer dans votre application
TagLib usuels
Une liste hébergé par Jakarta taglibs/
Benchmark (1.1)
BSF (1.1)
Cache (1.2)
DateTime (1.1)
I18N (1.1)
Input (1.1)
IO (1.1)
JMS (1.1)
JNDI (1.1)
Log (1.1)
Mailer (1.1)
Random (1.1)
RDC - Reusable Dialog Components (2.0)
Regexp (1.1)
Scrape (1.1)
String (1.1)
XTags (1.1)
TagLib usuels
jsp (les actions standards)
jsp:useBean associe une instance d’objet Java(Bean)
jsp:setProperty positionne la valeur d’une propriété d’un bean
jsp:getProperty récupère la valeur de la propriété d’un bean
jsp:include inclut le contenu du page statique ou dynamique
jsp:invoke invoque l’exécution d’un fragment (JSP, …)
jsp:forward redirige le traitement de la requête à un autre script
jsp:body
jsp:doBody appelle le traitement des sous-éléments (cf: TagFile)
jsp:elementinsère un élément (XML) dans le document
jsp:attributeattribut d’un élément inséré ou
jsp:output configure le prélude du document XML
jsp:param paramêtre (key/value) pour jsp:forward et jsp:include
jsp:text ajoute le texte à la sortie
jsp:plugin insère un objet externe (dépendant de l’UA)
jsp:fallback alternative en cas d’échec du jsp:plugin
jsp:params liste les jsp:param dans un jsp:plugin
Exemple de JSTL JSP
<% include file="header.jsp" %>
Plugin tag OBJECT or EMBED not supported by browser.
TagLib usuels
c (Core)
URI=" /jstl/core"
Expression Language
Implicit objects
pageContext, param, paramValues, header, headerValues, cookie,
initParam, pageScope, requestScope, sessionScope, applicationScope
Variables
catch, out, set, remove
Flow Control
if, choose (when, otherwise), forEach, forTokens
URL Management
import (paramredirect, param), url (param)
Exemple d’EL (Expression
Language)
Arithmétique ${3/0}Infinity ${10%4} 2 ${10 mod 4}
${(1==2) ? 3 : 4}
Comparaison ${1 < 2} true ${1 lt 2} true ${100.0 == 100}true ${100.0 eq 100}true ${'hip' > 'hit'} false
Exemple d’EL (Expression
Language)
Objets implicites
${param.custname} didier
${param["custname"]} didier
${header["host"]} mywebserver:8080
${header["accept"]} image/gif, image/jpeg, */*
${sessionScope.cart.numberOfItems}
${pageContext.request.contextPath}
Fonctions
<%@ taglib prefix="my" uri=" "%>
${my:reverse(param["custname"])} reidid
${my:reverse(my:reverse(param["custname"]))} didier
${my:countVowels(param["custname"])} 3
Exemple de JSTL Core
Variables
<% mycart.remove(bookId); %>
URL
Control Flow
...
...
...
TagLib usuels
fmt (Internationalization)
URI=" /fmt"
Locale
setLocale
Message formatting
bundle, setBundle, message (param)
Number and dateformatting
formatNumber, parseNumber,
formatDate, parseDate, setTimeZone, timeZone
Example
.
TagLib usuels
sql (SQL)
URI=" /jstl/sql"
Exemple …
SELECT * FROM customers
WHERE country = ’Algeria’
ORDER BY lastname
TagLib usuels x (XML)
URI=" /jstl/xml"
Expression Xpath
Objets implicites
$param:, $header:, $cookie:, $initParam:, $pageScope:, $requestScope:,
$sessionScope:, $applicationScope:
Exemple
$applicationScope.booklist/books/book[@id=$param:bookId]
Core
out, parse, set
Flow Control
if, choose (when,otherwise), forEach
Transformation
transform (param)
Exemple JSTL XML
Parsing
Variables et Sorties
select="$applicationScope.booklist/books/book[@id=$param:bookId]" />
Transformation
Exemple JSTL XML
$book/@id"/>;
JSPX
Motivation
Génération dynamique de documents XML avec les JSP
XHTML, SVG, SMIL, …
Utilisation des Namespaces
xmlns:jsp="http://java.sun.com/JSP/Page"
jsp:root, jsp:declaration, jsp:scriptlet, jsp:expression, jsp:directive.page, jsp:directive.include
Limites
Seulement une validation par la DTD
Pas de validation avec XML Schema
Pas de support du XInclude.
Génération d’un document HTML (i)
String getDateTimeStr(Locale l) {
DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM, l);
return df.format(new Date());
}
Example JSP in XML format
…
This is the output of a simple JSP using XML format.
getDateTimeStr(request.getLocale())
<p>This sentence is enclosed in a jsp:text element.</p>
Génération d’un document HTML (i)
…
This is the output of a simple JSP using XML format.
getDateTimeStr(request.getLocale())
<p>This sentence is enclosed in a jsp:text element.</p>
Exemple de JSPX
Génération d’un document SVG
<g opacity="0.95" transform="scale(1.05) rotate(15)">
${name}
</g>
${name}
Introduction au J2EE – Java 2 Enterprise Edition
Répartition Client-Serveur
Traitement coté client (User Agent)
extériorisation de l ’information
formats visualisables par le client
interactivité non lié au réseau
Interactivité requierant le serveur (RIA + Bayeux protocol)
Traitement coté serveur
serveur applicatif
conserve les traitements en interne (business logic)
adapté le document retourné au capacité du visualisateur
prise en compte des champs accept: communiqués par le client
charge le serveur
Le Scripting Serveur
Utilisation
Traitement des formulaires par le serveur
Génération de pages HTML à la volée
requête sur des bases de données, …
Les Techniques
Script générant du HTML
CGI : Common Gateway Interface, Fast-CGI
NSAPI, ISAPI, Servlets
Script embarqué dans des pages HTML
SSI : Server Side Include
SSS : Server Side Script
Active Server Pages (MicroSoft), SSJ (NS), JSP (Sun), PHP,
EJS (Express) ...
…
RDBMS
Application
tables
Web Browser Web Server EJB Server
HTML
HTTP
Session
Bean Bean
Entity
Bean
Entity
Bean
RMI
JDBC/SQL
XA
Servlet Servlet RMI
RDBMS
Application
tables
Web Browser Web Server EJB Server
HTML
HTTP
Session
Bean Bean
Entity
Bean
Entity
Bean
RMI
JDBC/SQL
XA
Servlet Servlet
RMI
State replication for failover
JavaEE et EMB (Enterprise Media Beans)
Web Server EJB Server
HTML/SMIL
HTTP
Enterprise
Media Beans
RMI/SSL
IIOP/SSL
Servlet,
Filter,
JSP, JSF
Servlet,
Filter, Enterprise
Beans Beans
RDBMS/ERP
DataSource
JDBC
JCA
web cam site
blah blah
blah blah
blah blah
blah blah
blah blah
MPEG,…
RTSP
xHTML/SMIL
HTTP
MPEG,…
RTSP
Streaming
Server
Media
Plugin
Media
Metadata Plugin
Repository
Stream
Repository
Web Browser
+ JMF, WMP,
RealOne
…
J2ME
Mobile Media
API (JSR135)
Web application
Partie « présentation » d’une application JavaEE
Servlet
Filter
JSP (Java Server Page)
JSTL (Java Server Tag Library)
JSF (Java Server Face)
+
Classes, bibliothèques (Jar File), …
Ressources (Document statiques, Images, Messages internationalisés (i18n), Propriétés …)
Packaging d’une application Web en JavaEE (Web Component)
Web Component
Une application Web (*.html, *.jsp, servlets, …) packagée dans un .jar
(.war) et est paramêtrée dans le fichier WEB-INF/web.xml
L’application est installée dans le répertoire webapps du serveur web JavaEE
Structure d’une Web Application Archive (.war)
*.html, *.png, *.jsp, …, applets.jar, midlets.jar
WEB-INF/web.xml
Fichier de déploiement
Paramêtrage des servlets, types MIME additionnels, …
WEB-INF/classes/
.class des servlets et des classes (JavaBean, …) associées
ressources additionnelles (localstring.properties, …)
WEB-INF/lib/
.jar additionnels provenant de tierce parties (comme des drivers JDBC,
TagLib (jsf, …), …
WEB-INF/tlds/
.tld décrivant les TagLibs
Le fichier WEB-INF/web.xml
Fichier de déploiement de l’application
Correspondance URI -> classes Servlets
Valeurs d’initialisation des Servlets
Valeurs d’environnement
Ressources
Références vers EB Home, DataSource, Mail Session, …
Types MIME supplémentaires
text/vnd.wap.wml, text/vnd.sun.j2me.app-descriptor, …
Contraintes de sécurité
…
EAR : ecom.ear
application
.xml
Rappel
Packaging d’une application JavaEE complète
EJB-JAR : ecom.jar
.class
.class
.class
ecom
.xml
Web App : ecomadmin.war
.htm
(servlet)
.class .jsp
web
.xml .png
applets
.jar
.tld
Web App : ecomcustomer.war
.htm
(servlet)
.class .jsp
web
.xml .png
midlets
.jar
.tld
Java application :
ecomshell.jar
.class
.class
.class
.mf
Servlet et Filter
Les Servlets
Servlets
Scripts serveur écrit en Java
Servlets de Base : FileServlet, CGIServlet, …
HttpServlet, SIPServlet, …
Exécution dans un espace isolé (Web Application)
javax.servlet
InputStream ServletInputStream
OutputStream ServletOutputStream
Object Servlet
Exception ServletException
GenericServlet
ServletConfig
ServletContext
ServletRequest
ServletResponse
SingleThreadModel
java.io
java.lang
javax.servlet.http
HttpServletContext
HttpServletRequest
HttpServletResponse
HttpServlet
HttpSession
HttpSessionBindingListener
Cookie
HttpUtils
Serializable
EventListener
Filter
L’API Servlet
javax.servlet et javax.servlet.http
Exemple de Servlet
Hello World !
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String pname = req.getParameter("name"); // Get a parameter
if(pname==null) pname="World !";
res.setContentType("text/html"); // Set the Content-Type header
PrintWriter out = res.getWriter(); // Get the output
out.println("");
out.println("Hello, " + pname + "");
out.println("");
out.println("Hello, " + pname);
out.println("");
out.flush();
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException { doGet(req, res); }
}
Servlets
Cycle de Vie (i)
Web Container
Servlet .class Chargement
Remarque :
spécifié lors du déploiement
Web Container
Servlet
Client
Client
Traitement de
1 à N requêtes
service()
Remarque :
l ’état est conservé
entre les requêtes
Web Container
Servlet
Initialisation
init()
Remarque :
spécifié lors
du déploiement
Web Container
Servlet
Destruction
destroy()
Remarque :
Shutdown du serveur, ...
La Requête
L ’exploration du serveur
public class ServerSnoop extends GenericServlet {
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");PrintWriter out = res.getWriter();
out.println("Server: getServletContext().getServerInfo(): " +
this.getServletContext().getServerInfo());
while(atts.hasMoreElements()){ // informations supplémentaires du constructeur
String att= (String)atts.nextElement();
out.println("Server: getServletContext().getAttribute(\""+att+"\"): " +
this.getServletContext().getAttribute(att);
}
out.println("Server: req.getServerName(): " + req.getServerName());
out.println("Server: req.getServerPort(): " + req.getServerPort());
} }
La Requête
L ’exploration du client
public class ClientSnoop extends GenericServlet {
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");PrintWriter out = res.getWriter();
out.println("Client: req.getRemoteHost(): " + req.getRemoteHost ());
out.println("req.getRemoteAddr(): " + req.getRemoteAddr ());
} }
La Requête
La récupération des paramêtres (POST ou GET)
public class ParameterSnoop extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException { doGet(req,res); }
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println("Query String:"); out.println(req.getQueryString()); out.println();
out.println("Request Parameters:");
Enumeration pnames = req.getParameterNames();
while (pnames .hasMoreElements()) {
String name = (String) pnames.nextElement();
String values[] = req.getParameterValues(name);
if (values != null) {
for (int i = 0; i < values.length; i++) {
out.println(name + " (" + i + "): " + values[i]);
}
} } } }
La Requête
La recupération des entêtes
public class HeaderSnoop extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.println("Request Headers:");
out.println();
while (enum.hasMoreElements()) {
String name = (String) enum.nextElement();
String value = req.getHeader(name);
if (value != null) {
out.println(name + ": " + value);
} } } }
La Requête
La recupération des Cookies
public class CookiesSnoop extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain"); PrintWriter out = res.getWriter();
out.println("Cookies:");
javax.servlet.http.Cookie[] cookies = req.getCookies();
for (int c=0;c<cookies.length;c++) {
out.print("Name:" + cookies[c].getName());
out.print("Value:" + cookies[c].getValue());
out.print("Domain:" + cookies[c].getDomain());
out.print("Path:" + cookies[c].getPath());
out.print("Secure:" + cookies[c].getSecure());
out.print("Version:" + cookies[c].getVersion());
out.print("MaxAge:" + cookies[c].getMaxAge());
out.println("Comment :" + cookies[c].getComment());
} } } }
La Requête
La récupération du flot d ’entrée
public class InputStreamSnoop extends GenericServlet {
public void service( ServletRequest req, ServletResponse res)
throws ServletException, IOException {
String contenttype=req.getContentType ();
int contentlength=req.getContentLength ();
2 flots de données possibles
java.io.BufferedReader in= req.getReader();
...
javax.servlet.ServletInputStream in= req.getInputStream();
…
Utilisation exclusive sinon IllegalStateException
Utilisation
décodage d’un corps en multipart/data
La Réponse
La réponse simple
public class Hello extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("");
out.println("Hello World");
out.println("");
out.println("Hello World");
out.println("");
} }
La Réponse
Maintien de la connexion (KeepAlive)
public class KeepAliveHello extends HttpServlet {
throws ServletException, IOException {
res.setContentType("text/html");
// Set up a PrintStream built around a special output stream
ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024);
PrintWriter out = new PrintWriter(bytes, true); // true forces flushing
out.println("");
out.println("Hello World");
out.println("");
out.println("Hello World");
out.println("");
res.setContentLength(bytes.size()); // Set the content length
bytes.writeTo(res.getOutputStream()); // Send the buffer
} }
La Réponse
Les codes d ’état et la journalisation
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
...
try {//
...
} catch (FileNotFoundException e) {
// utilise le journal de GenericServlet
this.log("Could not find file: " + e.getMessage());
// envoi du code 404
res.sendError(HttpServletResponse.SC_NOT_FOUND);
} catch (IOException e) {
// utilise le journal de ServletContext
this.getServletContext().log(e, "Problem sending file");
// envoi du code 500
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.toString());
}
}
La Réponse
L’ajout d ’entête
public class ClientPull extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res )
throws ServletException, IOException {
res.setContentType("text/plain"); PrintWriter out = res.getWriter();
res.setHeader("Refresh", "10");
out.println(new Date().toString());
} }
La Session javax.servlet.http.HttpSession
Le suivi de session
Le serveur maintient une session de 2 manières :
Cookie (Name: SESSIONID Value: To1010mC8601021835741167At)
les cookies peuvent être déactivés sur le navigateur
Réécriture des URLs
Ouverture/récupération d’une session
javax.servlet.http.HttpSession session = req.getSession(false);
// la session est récupérée ou null si elle n’existait pas déjà
javax.servlet.http.HttpSession session = req.getSession(true);
Invalidation d’une session
javax.servlet.http.HttpSession session = req.getSession(false);
session.invalidate(); // la session est invalidée (i.e. fermée)
La Session javax.servlet.http.HttpSession
Information sur la session
javax.servlet.http.HttpSession session = req.getSession(false);
L ’identifiant
String sessionid= session.getId(); // par exemple: To1010mC8601021835741167At
La date de création long datecreation= session.getCreationTime(); // nb de ms depuis 1/1/1970:00:00
La date du dernier accès
long datelastaccess= session.getLastAccessedTime();
Exemple
HttpSession session = req.getSession(true);
if(session.getLastAccessedTime() - session.getCreationTime() > 5*60*1000 ) {
session.invalidate();
}
La Session javax.servlet.http.HttpSession
Liaison d ’objets à une session
javax.servlet.http.HttpSession session = req.getSession(true);
Ajout/remplacement d ’une valeur void HttpSession.setAttribute(String name, Object value)
Suppression d ’une valeur
void HttpSession.removeAttribute(String name)
Récupération des valeurs/d ’une valeur
Enumeration HttpSession.getAttributeNames()
Object HttpSession.getAttribute(String name)
La Session javax.servlet.http.HttpSession
Exemple de liaison d ’objets
import mycybermarket.Cart; …
public void doGet(HttpServletRequest req, HttpServletResponse res) … {
Cart cart;
HttpSession session = req.getSession(true);
if((cart=(Cart)session.getAttribute("CART"))!=null) {
cart=CartFactory.create(); // new Cart( ... ); ou =cartHome.create();
session.setAttribute("CART",cart);
} ...
...
if(action.equals("exit") {
cart.releaseProducts();
session.removeAttribute("CART");
}
...
La Session
Observateurs sur la session
Motivations
réagir face à des événements intervenants dans la/les sessions
4 interfaces Listeners
HttpSessionActivationListener la session peut être passivée puis réactivée
HttpSessionListener
HttpSessionAttributeListener
changement sur les attributs d’une des sessions de l’application Web.
HttpSessionBindingListener
un objet peut être notifié de sa liaison/rupture à un session
La Session
Exemple de Observateur de Liaison
class CartBindingListener implements HttpSessionBindingListener {
Cart cart=null;
public CartBindingListener( ... ) { this.cart = new Cart( ... ); }
public void valueBound(HttpSessionBindingEvent event) {}
public void valueUnbound(HttpSessionBindingEvent event)
{ cart.releaseProducts();}
public void doGet(HttpServletRequest req, HttpServletResponse res) {
CartBindingListener cart;
HttpSession session = req.getSession(true);
CartBindingListener cart=(Cart)session.getValue("CART");
if(cart==null) { cart=new CartBindingListener( ... );
session.setAttribute("CART",cart); // valueBound est invoqué sur l ’objet lié
} …
session.removeAttribute ("CART"); // valueUnbound est invoqué sur l ’objet lié
Accès à des ressources de l'application JavaEE
Enterprise JavaBeans
DataSources (Bases de données)
JMS (Queues/Topics)
…
Accès aux Entreprise Beans
WEB-INF/web.xml
ejb/Cart
Session
myapp.beans.CartHome
myapp.beans.Cart
myapp.jar#Cart
ejb/CartLocal
Session
myapp.beans.CartLocalHome
myapp.beans.CartLocal
myapp.jar#Cart
Accès aux Entreprise Beans
Code
Context ctx = new InitialContext
// start transactions from client: get UserTransaction
UserTransaction utx= (UserTransaction)
initialContext.lookup("java:comp/UserTransaction");
// Connecting to CartLocalHome thru JNDI
ICartLocalHome cartLocalHome =
ctx.lookup("java:comp/env/ejb/CartLocal ");
ICartLocal cartLocal = cartLocalHome.create(SessionId);
Accès aux Entreprise Beans
via les annotations
@ManagedBean
public class CartServlet extends HttpServlet {
@EJB(mappedName = "LocalCart")
private ICart cart;
void doGet(...) {
...
cart.add(productId,qte, …) ;
….
}
Request Dispatch
Utilisé pour le MVC (Controleur)
Exemple
public class ForwardServlet extends HttpServlet {
public void doGet (HttpServletRequest request,
HttpServletResponse response) {
// Set the attribute and forward to hello.jsp
request.setAttribute ("action", "hello");
ServletContext context=getServletConfig().getServletContext().
context.getRequestDispatcher("/hello.jsp").forward(request, response);
}
}
Filtre (Filter)
Traitement s’interposant entre le client et la ressource
(Servlet, JSP, fichier) requise
en pré-traitement et/ou et post-Traitement
Chaînage de filtres (selon l’ordre de déclaration dans web.xml)
Exemple de filtres
Authentification
Conversion (Image), Transformation (XSLT, FOP)
Chiffrage/Compression (Image,Données gzip)
Audit/Journalisation, Caching
Load balancing/Redirection (304Filter)
API
javax.servlet.Filter
init(FilterConfig config)
doFilter(request,response,chain) { … chain.doFilter(request,response); … }
destroy()
Déploiement dans le descripteur web.xml
Exemple de Filtre
public class TraceFilter implements javax.servlet.Filter {
private String separator;
private FilterConfig filterConfig
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig= filterConfig;
this.separator = filterConfig.getInitParameter("fieldseparator");
}
public void doFilter(ServletRequest req,ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hreq = (HttpServletRequest)req;
long startTime = System.currentTimeMillis();
chain.doFilter(req, res);
long stopTime = System.currentTimeMillis();
log(hreq.getRemoteAddr()
+ separator + hreq.getServletPath() + separator + (stopTime-startTime));
}
private void log(String msg){ filterConfig.getServletContext().log(msg); }
}
Servlet 3.0 (JSR 315)
Servlet asynchrone
Support pour Comet et WebSockets
Annotations
@ServletSecurity, @MultipartConfig
Fragment web.xml
Support Multipart
...
Exemple de Servlet par Annotation
@WebServlet(name=”MyHelloServlet”,
urlPatterns={"/hello*", "/hi"},
initParams={ @InitParam(name="fr", value="Bonjour"),
@InitParam(name="es", value="Hola") }),
asyncSupported=true
)
public class HelloServlet extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse res) {
AsyncContext aCtx = req.startAsync(req, res);
….
}
}
JSR 224 JAX-WS
API pour les Web Services
Exemple
@WebService
public class Hello {
@WebMethod
public String sayHello(String name) { return "Hello "+ name; }
}
public class HelloAppClient {
@WebServiceRef(wsdlLocation = " ")
private static HelloService service;
public static void main(String[] args) {
Hello.endpoint.Hello port = service.getHelloPort();
System.out.println(port.sayHello("world"));
}}
Proxy client généré par wsimport -p hello
JSR-311
Java API for RESTful Web Services
Motivations
API Java for RESTful Services
Java 1.5 Annotation for POJO : @Path, @GET, @POST, …
Exemple
@Path("/library")
@Produces{"application/json"}
public class Library {
@GET @Path("/book")
public String getBooks() {...}
@GET @Path("/book/{isbn}")
public String getBook(@PathParm("isbn") String id) { … }
@POST @Path("/book/{isbn}")
@Consumes("application/x-www-form-urlencoded")
public String getBook(FormURLEncodedProperties formData) { … }
@POST @Path("/book/{isbn}")
@Consumes("multipart/related")
public String getBookMulti(MimeMultipart mimeMultipartData) { … }
@PUT @Path("/book/{isbn}")
public void addBook(@PathParam("isbn") String id, @QueryParam("name") String name) {...}
@DELETE @Path("/book/{id}")
public void removeBook(@PathParam("id") String id {...}
}
JSP & JSTL
JSP (Java Server Page)
Server Side Script
Insertion de SSS (syntaxe Java) dans les pages HTML
Avantage par rapport aux servlets
Insérable par des outils auteurs dans le code de pages
HTML
Extensible grâce aux JSTL
Spécification
JSR-52
JSR-152 JavaServer Pages 2.0 Specification
Implémentations
J2EESDK et Jakarta JASPER/TomCat
Insertion des scripts
Directives
< "java.util.*" %>
< "c" uri="WEB-INF/tld/core.tld" %>
Éléments de script
Scriplets <% code java %>
Déclarations <%! Déclarations %>
Expressions <%= expression %>
TagLib
Exemple de traitement d ’un
formulaire
Hello
<%
String pname; // déclaration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
%>
Mister <%=pname%>
<% } // fin du else %>
Scriptlet
(source Java)
Expression (EL)
Exemple de traitement d’un formulaire
<%@ method = "doPost" %>
Hello
<%
String pname; // déclaration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
%>
Mister <%=pname%>
<% } // fin du else %>
Directives
<% varname="value" %>
content-type, import,
extends, implements,
method, language
JSP : Exemple avec une session
JSP listant un « caddie » virtuel
<%
cart.processRequest(request);
%>
You have the following items in your cart:
<% String[] items = cart.getItems();
for (int i=0; i<items.length; i++) { %>
<% } %>
<%@ include file ="catalog.html" %>
Didier Donsez, 1995-2009, Dev. Web en JavaEE
JSP
package mycybermarket;
import javax.servlet.http.*; import java.util.Vector; import java.util.Enumeration;
public class MyCart {
Vector v = new Vector(); String submit = null; String item = null;
private void addItem(String name) { v.addElement(name); }
private void removeItem(String name) { v.removeElement(name); }
public void setItem(String name) { item = name; }
public String[] getItems() { String[] s = new String[v.size()]; v.copyInto(s); return s; }
public void processRequest(HttpServletRequest request) {
// null value for submit - user hit enter instead of clicking on "add" or "remove"
if (submit == null) addItem(item);
if (submit.equals("add")) addItem(item);
else if (submit.equals("remove")) removeItem(item);
reset(); // reset at the end of the request
}
private void reset() { submit = null; item = null; }
}
Génération des JSP
Compilation des JSP en classes Java
génération et compilation d ’une classe étendant HttpJspBas à la première invocation. e
Au runtime
la servlet JspServlet invoque le compilateur Jasper puis charge et exécute la méthode _jspService de la classe
HttpJspBase générée
Avant déploiement
Les JSP peuvent être aussi générées avant le déploiement (tâche )
JSP - Exemple de Génération
Parsing du document .jsp par JspServlet
Hello
<%
String pname; // déclaration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
%>
Mister <%=pname%>
<% } // fin du else %>
_jspx_html_data[0]
_jspx_html_data[1]
_jspx_html_data[2]
JSP - Exemple de Génération
chargement des fragments du document
public class jsp_0005chello_0002ejsphello_jsp_1 extends HttpJspBase {
static char[][] _jspx_html_data = null;
public jsp_0005chello_0002ejsphello_jsp_1( ) {
}
private static boolean _jspx_inited = false;
public final void _jspx_init() throws JspException {
ObjectInputStream oin = null;
int numStrings = 0;
try {
FileInputStream fin = new FileInputStream
("work\\%3A8080%2Fdemo\\C_0003a.test.jsphello.dat");
oin = new ObjectInputStream(fin);
_jspx_html_data = (char[][]) oin.readObject();
} catch (Exception ex) {
throw new JspException("Unable to open data file");
} finally {
if (oin != null)
try { oin.close(); } catch (IOException ignore) { }
}
JSP - Exemple de Génération la méthode _jspService (partie 1)
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
JspFactory _jspxFactory = null;PageContext pageContext = null;
HttpSession session = null; ServletContext application = null;
ServletConfig config = null; JspWriter out = null;
Object page = this; String _value = null;
try {
if (_jspx_inited == false) { _jspx_init(); _jspx_inited = true; }
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext
(this, request, response,"", true, 8192, true);
// objets implicites
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
// …
JSP - Exemple de Génération la méthode _jspService (partie 2)
// …suite de la méthode jspService
out.print(_jspx_html_data[0]);
// begin [file="C:\\test\\jsp\\hello.jsp";from=(4,2);to=(8,0)]
String pname; // d\u00e9claration de variable
pname = request.getParameter("name"); // request : objet implicite
if (pname== null) { out.println("World"); } else {
// end
out.print(_jspx_html_data[1]);
// begin [file="C:\\ test \\jsp\\hello.jsp";from=(9,10);to=(9,15)]
out.print(pname);
// end
out.print(_jspx_html_data[2]);
// begin [file="C:\\ test \\jsp\\hello.jsp";from=(10,2);to=(10,5)]
} // fin du else
// end
out.print(_jspx_html_data[3]);
} catch (Throwable t) {
if (out.getBufferSize() != 0) out.clear();
throw new JspException("Unknown exception: ", t);
} finally { out.flush(); _jspxFactory.releasePageContext(pageContext);
}
}
}
JSTL
Java Server Tag Library
Motivations
Extension des JSP par des tiers
Développement modulaire
Développement sans Java (pour Web Designer)
Principes
Le document contient des éléments (tag) supplémentaires
BodyTag.
JSTL usuels
JSTL
Usage
Directive
<%@ taglib uri="/WEB-INF/tlds/my-taglib.tld" prefix="my" %>
Invocation
some enclosed text here
Déploiement
WEB-INF/tlds/my-taglib.tld
Déclaration des classes implémentant la Tag Lib
WEB-INF/lib/my-taglib.jar
Jar file contenant les classes d’implémentation
TagLib usuels
Une liste non exhaustive …
jsp (action standard)
c (core)
fmt (formattage et internationalisation)
xml (xml, xpath et xslt)
sql (sql)
jsf/core, jsf/html, …
logic (Jakarta Struts)
tags (TagLib)
à déployer dans votre application
TagLib usuels
Une liste hébergé par Jakarta taglibs/
Benchmark (1.1)
BSF (1.1)
Cache (1.2)
DateTime (1.1)
I18N (1.1)
Input (1.1)
IO (1.1)
JMS (1.1)
JNDI (1.1)
Log (1.1)
Mailer (1.1)
Random (1.1)
RDC - Reusable Dialog Components (2.0)
Regexp (1.1)
Scrape (1.1)
String (1.1)
XTags (1.1)
TagLib usuels
jsp (les actions standards)
jsp:useBean associe une instance d’objet Java(Bean)
jsp:setProperty positionne la valeur d’une propriété d’un bean
jsp:getProperty récupère la valeur de la propriété d’un bean
jsp:include inclut le contenu du page statique ou dynamique
jsp:invoke invoque l’exécution d’un fragment (JSP, …)
jsp:forward redirige le traitement de la requête à un autre script
jsp:body
jsp:doBody appelle le traitement des sous-éléments (cf: TagFile)
jsp:elementinsère un élément (XML) dans le document
jsp:attributeattribut d’un élément inséré ou
jsp:output configure le prélude du document XML
jsp:param paramêtre (key/value) pour jsp:forward et jsp:include
jsp:text ajoute le texte à la sortie
jsp:plugin insère un objet externe (dépendant de l’UA)
jsp:fallback alternative en cas d’échec du jsp:plugin
jsp:params liste les jsp:param dans un jsp:plugin
Exemple de JSTL JSP
Plugin tag OBJECT or EMBED not supported by browser.
TagLib usuels
c (Core)
URI=" /jstl/core"
Expression Language
Implicit objects
pageContext, param, paramValues, header, headerValues, cookie,
initParam, pageScope, requestScope, sessionScope, applicationScope
Variables
catch, out, set, remove
Flow Control
if, choose (when, otherwise), forEach, forTokens
URL Management
import (paramredirect, param), url (param)
Exemple d’EL (Expression
Language)
Arithmétique ${3/0}Infinity ${10%4} 2 ${10 mod 4}
${(1==2) ? 3 : 4}
Comparaison ${1 < 2} true ${1 lt 2} true ${100.0 == 100}true ${100.0 eq 100}true ${'hip' > 'hit'} false
Exemple d’EL (Expression
Language)
Objets implicites
${param.custname} didier
${param["custname"]} didier
${header["host"]} mywebserver:8080
${header["accept"]} image/gif, image/jpeg, */*
${sessionScope.cart.numberOfItems}
${pageContext.request.contextPath}
Fonctions
<%@ taglib prefix="my" uri=" "%>
${my:reverse(param["custname"])} reidid
${my:reverse(my:reverse(param["custname"]))} didier
${my:countVowels(param["custname"])} 3
Exemple de JSTL Core
Variables
<% mycart.remove(bookId); %>
URL
Control Flow
...
...
...
TagLib usuels
fmt (Internationalization)
URI=" /fmt"
Locale
setLocale
Message formatting
bundle, setBundle, message (param)
Number and dateformatting
formatNumber, parseNumber,
formatDate, parseDate, setTimeZone, timeZone
Example
.
TagLib usuels
sql (SQL)
URI=" /jstl/sql"
Exemple …
SELECT * FROM customers
WHERE country = ’Algeria’
ORDER BY lastname
TagLib usuels x (XML)
URI=" /jstl/xml"
Expression Xpath
Objets implicites
$param:, $header:, $cookie:, $initParam:, $pageScope:, $requestScope:,
$sessionScope:, $applicationScope:
Exemple
Core
out, parse, set
Flow Control
if, choose (when,otherwise), forEach
Transformation
transform (param)
Exemple JSTL XML
Parsing
Variables et Sorties
select="$applicationScope.booklist/books/book[@id=$param:bookId]" />
Transformation
Exemple JSTL XML
$book/@id"/>;
JSPX
Motivation
Génération dynamique de documents XML avec les JSP
XHTML, SVG, SMIL, …
Utilisation des Namespaces
xmlns:jsp="http://java.sun.com/JSP/Page"
jsp:root, jsp:declaration, jsp:scriptlet, jsp:expression, jsp:directive.page, jsp:directive.include
Limites
Seulement une validation par la DTD
Pas de validation avec XML Schema
Pas de support du XInclude.
Génération d’un document HTML (i)
String getDateTimeStr(Locale l) {
DateFormat df = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM, l);
return df.format(new Date());
}
Example JSP in XML format
…
This is the output of a simple JSP using XML format.
getDateTimeStr(request.getLocale())
<p>This sentence is enclosed in a jsp:text element.</p>
Génération d’un document HTML (i)
…
This is the output of a simple JSP using XML format.
getDateTimeStr(request.getLocale())
<p>This sentence is enclosed in a jsp:text element.</p>
Exemple de JSPX
Génération d’un document SVG
<g opacity="0.95" transform="scale(1.05) rotate(15)">
${name}
</g>
${name}