1.69k likes | 2.25k Views
Java Enterprise Edition Ce document a été contient des parties adaptées de support de cours de P.Y. Gibello , T . Dandelot et C. Dumoulin
E N D
Java Enterprise Edition Ce document a été contient des parties adaptées de support de cours de P.Y. Gibello, T. Dandelot et C. Dumoulin Le contenu de ce site est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 France. Java EE
Introduction à JEE Historique – Architecture - Offre
Historique Java http://docs.oracle.com/javase/6/docs/api/ http://docs.oracle.com/javaee/6/api/
Java EE - Objectifs • Faciliter le développement de nouvelles applications java à base de composants • Intégration avec les systèmes d’information existants • Support pour les applications « critiques » de l’entreprise • haute disponibilité, • tolérance aux pannes, • montée en charge, • sécurité • etc.
Architecture • Décompose le système à concevoir en • applications, en composants applicatifs, • analyse descendante jusqu’aux modules, aux classes gestionnaires, aux fonctions ou méthodes • Modules ou Objets gestionnaire, pour l’architecture logicielle • Représente les fonctions du système • Implémente les fonctions et sous-fonctions des cas d’utilisation • Services (ou fonctions) de gestion de données • CRUD (Create, Read, Update, Delete) sur les données métier • Services de recherche sur les données métier • services métiers • Transactions / Paiements • Calculs
Architectures informatiques • Architectures pour une solution projet : • Architectures logiques • applicative, • métier • Architectures techniques • logicielle, • système, • réseau, • matérielle.
Architecture logique 4 tiers • IHM (ou GUI) : client • Frontal (ou front-end) : présentation • Dorsal (ou back-end) : métier • Persistence: base de données T1 T2+T3 T2 T3 T4
Mutualiser le code métier T1 T1+T2 T2 Site Web T2 Frontal API T3 T4
Java EE – C’est quoi? • http://java.sun.com/javaee • Spécifications • Modèle de programmation • Implémentation de référence • Standard en évolution depuis 1997 • J2EE 1.0 à 1.4 en 2003, etc... • Au départ, applications Web n-tiers • Présentation (Servlets puis JSP), essentiellement HTTP • Logique métier : EJB • Données : JDBC • Puis infrastructure de support standard pour EAI • Facteurs de rationalisation majeurs (JTA, JMS, JCA, Web Services) • Evolution de progiciels existants vers Java EE
Architecture 4 tiers JEE JDBC JMS JTA JCA JAAS JavaMail JNDI … WEB Container T2 Browser Servlets JSPs T1 HTTP html T4 DB jdbc RMI / IIOP Appel local JVM T1+T2 Applets java/flash T3 SOAP, REST RMI / IIOP EJBs xxxx public static void main(…) { T4 T1+T2 EIS EJB Container Java Application Java EE Application Server
Offre • Commerciale • Oracle (ex BEA) WebLogic • IBM Websphere (n°1) • Open Source • JBoss (n°1 en nombre de déploiements) • Oracle (ex Sun) Glassfish (« Platform edition ») • OW2 JOnAS • Apache Geronimo (« Communityedition » de IBM Websphere) • openEjb • Open Source conteneur web uniquement : • Tomcat • Jetty
Conteneur Webcouche de présentation Servlet - WAR – JSP – taglib
Conteneur Web 1/2 webapp Webapp web.xml html html html Servlet jsp Servlet Servlet Servlet Servlet jpg css jar js html
Conteneur Web 2/2 • Contient des applications Web dans un répertoire • Une application web est une arborescence de fichier • mywebapp/WEB-INF/web.xml • mywebapp/WEB-INF/classes/*.class • mywebapp/WEB-INF/lib/*.jar • mywebapp/**/*.* • Un fichier « .war » est une archive zip de cette arborescence
Application Web • Servlets • Code java exécuté sur le serveur pour retourner une page HTML • Génération de contenu Web dynamique • JSP: Java Server Pages • Mélange de HTML/XML et de code java • Librairies d ’extensions (« taglibs») • Pré-compilation en servlet
Servlet • Programme java appelable depuis une URL • Classe qui hérite de javax.servlet.http.HttpServlet • Cycle de vie de HttpServlet • init() : 1er appel • service() : chaque appel, redirection vers doGet() ou doPost() • destroy() : arrêt du serveur WEB • Appel d’une servlet • URL GET : http://myserver/mywapp/HelloWorld : doGet() • <formmethod="post" target="…"> : doPost(),
Exemple de servlet import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet{ public voidservice(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException { response.setContentType("text/html"); PrintWriterout= response.getWriter(); out.println("<html><body>"); out.println("<h1>hello word !</h1>"); out.println("</body></html>"); } }
Ecrire une Servlet • Classe qui hérite de la javax.servlet.Servlet • Surcharger la méthode d ’initialisation init(), • Utiliser la méthode getInitParameter() • Surcharger une méthode de gestion d’appel • doPost(), doGet(), doPut(), doDelete(), doOptions() • Analyser la requête, • Classe HttpServletRequest • getParameter(), getCookie(), getSession() • Utiliser la classe HttpServletResponse pour répondre • getWriter(), setContentType(), setCookie()
formulaire et Servlet • Champs des formulaires directement dans des variables : <FORM ACTION="testServlet" METHOD="POST"> Votre nom : <INPUT TYPE=TEXT NAME="nom"> Votre âge : <INPUT TYPE=TEXT NAME="age"> <INPUT TYPE=SUBMIT VALUE="Ok"> </FORM> • Dans TestServlet.doGet(), l’objet requestcontient les saisies: • request.getParameter("nom") • request.getParameter("age") publicvoiddoGet( HttpServletRequestrequest, HttpServletResponseresponse) ...{ … out.println("Bonjour " + request.getParameter("nom")); …
Déployer une servlet • Recopier l’application web sous $tomcat/webapps • une archive .war ou • Un répertoire • Contenu de l’application web • sous-répertoire « WEB-INF/ » • web.xml : déclaration et paramètres de servlets • /lib/ : pour les .jar, • /classes/ pour les .class
Déclaration de la servlet apache-tomcat-7.0.30/webapps/myapp/WEB-INF/web.xml <web-app> <servlet> <servlet-name>servletHello</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletHello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app> http://localhost:8080/myapp/hello
Autour des Servlets • Gestion de la session : HttpServletRequest.getSession() • données de contexte à durée de vie courte • stockées sur le serveur • addAttribute(), getAttribute(), setMaxInactiveInterval() • Gestion des cookies : HttpServletRequest.getCookies() • données de contexte à durée de vie plus longue • stockées sur le poste client • setName(), setValue(), setMaxAge() • Filtre • Transforme des requêtes et/ou des réponses • Classe qui implémente javax.servlet.Filter • Déclaré dans web.xml comme une Servlet
JSP • Java Server Pages • Intégration de code serveur dans un fichier HTML • mêmes principes que PHP • Code java dans des balises <%...%> • Les pages JSP ont l’extension « .jsp » • L’interpréteur JSP génère une classe de servlet « .java » par JSP • des variables accessibles dans des pages(session, application, request, response)
Exemple de JSP Directive <%@page import="java.util.*" %> <HTML> <HEAD> <TITLE>Test HelloWorl en JSP</TITLE> </HEAD> <BODY> <% out.println("Hello world !"); out.println("Hello " + request.getParameter("name"); %> <p>Todayis<%= new Date() %> </BODY> </HTML> Scriptlet Expression
interprétation script Coté serveur <HTML> <BODY> <%="Hello world !"%> <script type="text/javascript"><!– var now = new Date(); document.write("todayis " + now.getDay());//--> </script> </BODY></HTML> Vue utilisateur interprétation serveur Hello world Todaynumberis19 Coté client <HTML> <BODY> Hello world ! <script type="text/javascript"><!– var now = new Date(); document.write("todayis " + now.getDay());//--> </script> </BODY></HTML> interprétation client
variables prédéfinies JSP • out : flux de sortie dans la réponse HTTP au client. • utiliser println() • request : objet représentant la requête HTTP • utiliser getParameter("name"), getCookies(), forward() • response : objet représentant la réponse HTTP • outest retournée par response.getWriter() • utiliser setCookie(new Cookie("name","value")) • session : objet représentant la session HTTP • utiliser setAttribute("name"), getAttribute("name"), removeAttribute("name") • La session de l’utilisateur est retourner par request.getSession(false) • request.getSession(true) crée et retourne une nouvelle session (déconnexion ou logout) • pageContext: objet représentant le contexte d'une page • Facilite l'accès au contexte de l'application web • utiliser setAttribute("name") pour donner des paramètres aux taglibs • Utiliser foward("url") pour déléguer la réponse à une autre page
formulaire et JSP • Champs des formulaires directement dans des variables : <FORM ACTION="test.jsp" METHOD="POST"> Votre nom : <INPUT TYPE=TEXT NAME="nom"> Votre âge : <INPUT TYPE=TEXT NAME="age"> <INPUT TYPE=SUBMIT VALUE="Ok"> </FORM> • Dans test.jsp, l’objet requestcontient les saisies: <% request.getParameter("nom") request.getParameter("age") %> • On peut écrire en réponse dans test.jsp: ... Bonjour <%out.println(request.getParameter("nom")); %> ...
syntaxe JSP • <% … %> : scriptlet • <%! … > : déclaration servlet <%! intmyVariable = 0; %> • <%-- Voici un commentaire JSP --%> • <%= … %> : expression (pas de ; final) • <%@... %> : directive <%@page import="…", <%@include page="url" • <jsp:…> : tag jsp <jsp:include>, <jsp:forward> • TagLib JSTL <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> • Autres TagLib : Struts2, Tiles, Spring MVC, etc.
Forward vs redirect • Forward utilisabledans un même war • Redirect sinon redirect <jsp:forwardpage="/jsp/welcome.jsp"/> Page A Page B Page C forward this.getServletConfig().getServletContext().getRequestDispatcher( "/JSP/Demo.hello.jsp").forward(request,response);
Forward pour les erreurs Page1.jsp Nb pizza incorrect … <% if (nbPizza<=0) { %> <jsp:forward page="Page1.jsp"> <jsp:paramname=”errMsg" value=”Nb pizza incorrect" /> </jsp:forward> <% } %> -2 Page 2.jsp
Utilisation des taglibs 1/2 • Rajout des jars correspondant dans WEB-INF/lib • WEB-INF/lib/jstl.jar • WEB-INF/lib/standard.jar • Exemple : <%@ tagliburi="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <html><body> <% pageContext.setAttribute("now",newjava.util.Date()); %>" …<fmt:formatDate pattern="yyyy-MM-dd" value="${now}" /> … </body></html>
Utilisation des taglibs 1/2 … code HTML … <jsp:useBean id=“user” class=“com.acme.EndUser” scope=“session” /> … code HTML … <? user.setName(“Dupont”); ?> <h2>Welcome, <c:out value="${user.name}”/> Ou <? EndUser user = new EndUser(); user.setName(“Dupont”); ?> <h2>Welcome, ${user.name}”
Conteneur Webcouche de persistance JDBC – Transaction
Java DataBaseConnectivity • Librairie d’interfaces java qui définisse la communication avec une base de données • Package « java.sql » • classe « DriverManager », interface « Driver » • démarrage d’une connexion • interfaces « Connection », « DatabaseMetaData » • Gestion d’une connexion et création de requêtes SQL • interface « Statement » et spécialisations • gestion, exécution d’une requête SQL • interfaces « ResultSet », « ResultsetMetaData » • gestion des résultats de requête SQL Application Java JDBC DriverManager MySQL JDBC Driver Oracle JDBC Driver MySQL Oracle
Connexion via JDBC • Classe DriverManager • DriverManager.getConnection(url,user,password) • Interface « java.sql.Connection » • Gère la connection à la base • close(), getMetaData() • Création d'une nouvelle requête • Statementstmt = createStatement(); • prepareStatement("select a from b where c=?") • pour optimisation, ‘ ? ’ = paramètre, ordre important • prepareCall("? = call proc_stock[?,?]") • procédure stockée (attention à la portabilité !) • Gestion du transactionnel • commit(), rollback(), setAutoCommit(boolean) Temps d'exécution long À considérer comme monothread
Exemple de connexion /** retourne une connection à une base de données accessible via JDBC * @paramdbURL - URL de la base de données * @paramdriverClassName - nom complet de la classe qui sert de driver JDBC * @param user - nom de compte utilisateur de la base de données * @parampassword - mot de passe associé au compte utilisateur */ public Connectionconnect(String dbURL, String driverClassName, String user, String password) throws Exception { // configure le DriverManager pour charger le driver try{ Object drv = Class.forName(driverClassName).newInstance(); } catch( Exception e) { e.printStackTrace(); throw e; } Connextionconnection = null; try { connection = DriverManager.getConnection(dbURL, user, password); return connection; } catch( SQLException se) { se.printStackTrace(); throw se; } }
Exemple de update • Connectioncnx = DriverManager.getConnection("jdbc:mysql://localhost:3306/pizzadb","com.mysql.jdbc.Driver","user","****"); • PreparedStatementupdateVentes = cnx.preparedStatement("UPDATE CAFE SET VENTE = ? WHERE NOM_CAFE LIKE ?");updateVentes.setInt(1,50);updateVentes.setString(2, "Colombian");updateVentes.executeUpdate(); • Statementstt = cnx.createStatement();stt.executeQuery("UPDATE CAFE SET VENTE = 50 WHERE NOM_CAFE LIKE 'Colombian' ");
Requêtes via JDBC • « Statement » représente une requête • Exécution d’une requête SQL • Resulsetres = statement.executeQuery("select …"); • intnbRows = statement.executeUpdate("update …"); • Pagination des résultats • setMaxRows(n), getMoreResults() • contrôle de l’exécution de la requête • setQueryTimeout(int seconds), cancel() • PreparedStatement, CallableStatement • set<Type>(n°param,valeur) avec pour <Type> : • String, Long, Double, BigDecimal, Boolean, Date, etc.
Résultats via JDBC • « Resultset » représente le résultat d’une requête • méthodes principales : • get<Type>(nom_colonne) • next() • exemple: while(rst.next()) { … gestion d ’une ligne … } • getMetaData() • « ResultsetMetaData » décrit le résultat (= la table si « select * ») • getColumnCount(), getColumnType()isNullable(), getColumnLabel(), etc.
Exemple de insert Pizza p = new Pizza("royale","tomato"); Statementstt = cnx.createStatement();intnbLigneCrees = stt.executeUpdate("INSERT INTO pizza (pizza_name,pizza_type) VALUES ('"+p.getPizzaName()+"','"+p.getPizzaType()+"')",Statement.RETURN_GENERATED_KEYS); ResultSetgeneratedKeys= stt.getGeneratedKeys(); if (generatedKeys.next()) { p.setId(generatedKeys.getLong(1)); } MySQL ALTER TABLE pizza CHANGE pizza_idpizza_idBIGINT( 20 ) NOT NULL AUTO_INCREMENT
Exemple de select // affiche les noms des cplonnes puis chaque ligne de résultat de la requête Statementstmt = connection.createStatement(); ResultSetrst = stmt.executeQuery("select c.chatRoomName, t.topicName, c.language, fromChatRoom c, TopicCategory t wherec.topicCategoryId = c.Id order by topicName, chatRoomName"); ResultSetMetaDatarstData = rst.getMetaData(); Collection<ChatRoom> chatRooms = new Vector<ChatRoom>(); while(rst.next() == true) { ChatRoomchatRoom = new ChatRoom(); chatRoom.setRoomName(rst.getString("chatRoomName")); ... chatRooms.add(chatRoom); } // fermeture de la requête et de ses Resultset associés stmt.close();
Transactions sous MySQL • Transactions en SQL • BEGIN, COMMIT, ROLLBACK, CHECKPOINT • option AUTOCOMMIT • Note : les DDL (create, alter, drop table) sont toujours AUTOCOMMIT • Accès concurrents : ligne ou table bloquée jusqu’au commit ou rollback • LOCK TABLE • SELECT … FOR UPDATE • Gestion optimistes des accès concurrents • Moteurs pour la base MySQL • InnoDB : foreignkeys, select for update, stockage optimisé • MyISAM : plus rapide en lecture • MEMORY : pas de stockage sur le disque • NDBCluster : table répartie sur plusieurs serveurs
Illustration d’une transaction • Table possessions (d’actions par utilisateurs) • Table comptes • Scénario 1 : l’utilisateur A achète 200 actions Axa à l’utilisateur B pour 37 euros
gestion optimiste des accès concurrents • Scénario 1 • Scénario 2 : l’utilisateur C achète aussi 400 actions Axa à l’utilisateur B pendant le scénario 1
Exemple de transaction JDBC • cnx.setAutoCommit(false);PreparedStatementupdateVentes = cnx.prepareStatement("UPDATE CAFE SET VENTE = ? WHERE NOM_CAFE LIKE ?");updateVentes.setInt(1,50);updateVentes.setString(2, "Colombian");updateVentes.executeUpdate();PreparedStatementupdateTotal = cnx.prepareStatement("UPDATE CAFE SET TOTAL = TOTAL + ? WHERE" + "NOM_CAFE LIKE ?");updateTotal.setInt(1,50);updateTotal.setString(2,"Colombian");updateTotal.executeUpdate();cnx.commit(); Cet exemple ne gère pas les accès concurrents
Log4j Introduction au système de trace coté serveur
Log4j • Librairie de génération de traces dans un fichier • Utiliser des fichiers de log au lieu de System.out • Types de traces : ERROR, INFO, DEBUG • Installation : log4j-<version>.jar dans le CLASSPATH • Logger : générateur de la trace • Appender : destination de la trace • LayoutPattern : format de la trace • Configuration • Log4j.properties • Log4j.xml
Exemple de config. log4j • <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> • <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> • <layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%d%t %c{2} - %m%n"/> • </layout></appender> • <categoryname="fr.isen"> • <priority value="DEBUG"/> • </category> • <root> • <priority value="ERROR"/> • <appender-ref ref="ConsoleAppender"/> • </root></log4j:configuration>
Exemple de code log4j • public class DAOBase { • ... • final static Logger logger = Logger.getLogger(DAOBase.class); • ... • public void aMethod() { • ... • connection = DriverManager.getConnection(dbURL, user, pwd); • if(logger.isDebugEnabled()) { • logger.debug("connected to " + dbURL); • } • ....