La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

UV JSP JSP : Java Server Page

Présentations similaires


Présentation au sujet: "UV JSP JSP : Java Server Page"— Transcription de la présentation:

1 UV JSP JSP : Java Server Page
CURSUS DE FORMATION AUX NOUVELLES TECHNOLOGIES DE DEVELOPPEMENT UV JSP

2 Plan du cours Rappel sur les applications Web
Les techniques côté serveur Gestion des cookies Les Java Server Pages (JSP)

3 Applications Web Serveur Client Serveur Web Internet/Intranet
Environnement d ’exécution Source de données Script/programme serveur Client Requête (http,…) 2e niveau Navigateur Web 3e niveau Réponse 1er niveau

4 Architecture 3 niveaux : niveau 1: présentation niveau 2: applicatif
navigateur + serveur Web niveau 2: applicatif script ou programme niveau 3: données données nécessaires au niveau 2

5 Déroulement Une application Web type :
1: recueille les données utilisateur (niveau 1) 2: envoie une requête au serveur Web 3: exécute le programme serveur requis (niveau 2&3) 4: assemble/renvoie les données vers le navigateur (niveau 1)

6 1: Collecte des données utilisateur
Quelques solutions pour le client : très utilisée : formulaire HTML saisie de champs puis « submit » validation par scripts (JavaScript) nouvelle : applets Java : connexion socket / RMI avec le serveur Web mise en forme et validation des données ...

7 2: Requête HTTP vers le serveur Web
contient : l ’URL de la ressource à accéder (page,script,prog) les données de formatage (le cas échéant) des infos d ’en-tête complémentaires requête GET : pour extraire des informations sur le serveur intègre les données de formatage à l ’URL value1&… requête POST : pour modifier les données sur le serveur données de la page assemblées/envoyées vers le serveur

8 3: Exécution d ’un script/prog. serveur
Avec la requête http, le serveur Web : 1) identifie le type d ’environnement d ’exploitation à charger (mapping) en fonction de l ’extension du fichier (.jsp, .cgi, ...) ou du répertoire où il se trouve (cgi-bin/, servlet/) 2) charge l ’environnement d’exécution (run-time) interpréteur Perl pour les programmes cgi en perl JVM pour les servlets Java, ...

9 4: Retour des résultats au navigateur
Le script/prog côté serveur : précise le type de contenu (HTML, XML, images,) intègre la réponse dans un flot de sortie Le navigateur : définit le type MIME dans l ’en-tête (text/html,…) et affiche les données en fonction duplication de l’environnement (variables, exécution), mémoire allouée, copie du programme, … retourne (en général) du HTML

10 Techniques côté serveur
CGI (Common Gateway Interface) ASP (Microsoft) Servlets Java et JSP (Sun)

11 CGI (rappel) Principe :
un processus par requête est lancé sur le serveur Serveur Web Interface CGI Env. execution Var. env. Programme Processus 1 Env. execution Var. env. Programme Processus 3 Env. execution Var. env. Programme Processus 2

12 CGI Avantages : Inconvénients :
gratuit, pris en charge par tous les serveurs Web actuels peut être écrit dans n’importe quel langage (surtout perl) Inconvénients : manque d’évolutivité (plusieurs processus créés) serveur très sollicité si plusieurs requêtes au même moment amélioré par : FastCGI : instance partagée des programmes CGI mod_perl (Apache) : script CGI interprété et exécuté dans le serveur Web assez lent parfois difficile à développer

13 Technologies J2EE : les JSP
Les Pages JSP: La technologie JSP permet d'embarquer des composants dans une page et de laisser ces derniers générer la page qui sera finalement renvoyée au client Une page JSP peut contenir du code HTML, du code Java et des composants JavaBean JSP est en réalité une extension du modèle Servlet : lors du premier accès a la page JSP, le conteneur Web la compile en Servlet Permet de nettement séparer la présentation du code métier (Concepteurs Web, développeurs)

14 Technologies J2EE : les JSP
Pages JSP JSP fournit une interface standard basée sur XML permettant de définir des balises (tags) personnalisées et les regrouper dans des bibliothèques de balises (taglibs) Avec J2EE, la spécification JSP a atteint la version 1.1

15 Technologies J2EE : les JSP
Architecture typique d'une application Web Navigateur Conteneur Web Entrepôt de données JSP HTTP(s) HTML, XML Servlet

16 Les JSP (Java Server Pages)
Réponse aux ASP/PHP/embedded perl, etc... Technologie qui permet de mixer Java et HTML <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD><TITLE>Welcome to Our Store</TITLE></HEAD> <BODY> <H1>Welcome to Our Store</H1> <SMALL>Welcome, <!-- User name is "New User" for first-time visitors --> <% out.println(Utils.getUserNameFromCookie(request)); %> To access your account settings, click <A HREF="Account-Settings.html">here.</A></SMALL> <P> Regular HTML for all the rest of the on-line store's Web page. </BODY></HTML>

17 Un exemple de JSP/Servlet en Java
package hall; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); out.println("Hello World");out.flush(); }

18 Introduction Gestion des formulaires HTML
La partie compliquée = paramètres du formulaire Visibles ou non dans l'URL (GET/POST) Ces paramètres doivent être décodés ! Avec les servlets : un vrai plaisir !

19 Récupèrer les paramètres
Méthode getParameter() Fonctionne avec GET ou POST public class ShowParameters extends HttpServlet { public void doGet(HttpServletRequest request,...) { out.println(request.getParameter(“param1”)); Enumeration paramNames=request.getParameterNames(); String[] paramValues = request.getParameterValues(paramNames); }

20 Les cookies Morceaux d’informations envoyés par le serveur
… et renvoyés par le client quand il revient visiter le même URL Durée de vie réglable Permet la persistance

21 A quoi ça sert ? Identification des utilisateurs (e-commerce)
Eviter la saisie d’informations à répétition login, password, adresse, téléphone… Gérer des « préférences utilisateur » sites portails… ... Identification des utilisateurs (e-commerce) Une application typique est le caddie dans le domaine de l'e-commerce : un utilisateur sélectionne un "item" dans une page pour l'ajouter dans son caddie, puis continue d'en sélectionner d'autres dans d'autres pages. Comme chaque connexion Http est fermée après chaque envoi de page, comment le serveur peut-il savoir qu'il s'agit du même utilisateur qui sélectionne un item diffèrent dans une autre page ? Les cookies constituent un bon moyen (cf suivi de session) Eviter la saisie d’informations à répétition (login, passwd, …) : Pour des site Web où l'utilisateur doit s'authentifier pour accéder à des services… Principe : qd l'utilisateur s'enregistre, un cookie est envoyé avec un unique ID. Qd il se reconnecte plus tard, le navigateur renvoie son user ID. Le serveur vérifie s'il est déjà enregistré et ne requière alors pas une nouvelle session d'authentification Gérer des « préférences utilisateur » Certains sites portails vous laisse "customizer" la page principal.

22 Cookie et sécurité ? Jamais interprété ou exécuté : pas de virus
Un cookie est limité à 4KB et les navigateurs se limitent à 300 cookies (20 par site) : pas de surcharge de disque Bien pour rendre privées des données non sensibles nom, adresse, … … mais ne constitue pas un traitement sérieux de la sécurité

23 Gestion des cookies ? Utiliser les fonctions de l ’API des servlets…
créer un cookie : classe Cookie, écrire/lire un cookie : addCookie(cookie), getCookies(), positionner des attributs d’un cookie : cookie.setXxx(…) Exemple d'envoi d'un cookie : ... String nom = request.getParameter("nom"); Cookie unCookie = new Cookie("nom", nom); ...ici positionner des attributs si on le désire response.addCookie(unCookie);

24 Création d'un cookie 2 arguments de type java.lang.String :
Cookie unCookie = new Cookie(name, value); 2 arguments de type java.lang.String : name et value caractères non autorisés : espace blanc [ ] ( ) = , " / : ;

25 Attributs des cookies getValue/setValue getName/setName
getComment/setComment getMaxAge/setMaxAge : délai restant avant expiration du cookie (en seconde) par défaut : pour la session courante getPath/setPath : répertoire où s'applique le cookie dir. courant ou pages spécifiques

26 Récupération des cookies
Exemple de récupération des cookies Cookie [] cookies = request.getCookies(); String nom = getCookieValue(cookies, "nom", "non trouvé"); ... public static String getCookieValue(Cookie [] cookies, String cookieName, String defaultValue) { for(int i=0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if(cookieName.equals(cookie.getName()) return(cookie.getValue()); } return(defaultValue); }

27 Temps d'expiration Par défaut, durée de vie d'un cookie = la connexion. Si on veut que le cookie soit sauvé sur disque, modifier sa durée de vie : public static final int SECONDS_PER_YEAR = 60*60*24*365; cookie.setMaxAge(SECONDS_PER_YEAR);

28 Principes de base et architecture JSP
But des JSP : simplifier la création et l'administration des pages Web dynamiques, en séparant le contenu de la présentation Les pages JSP ne sont que des fichiers contenant du code HTML ou XML standard et de nouvelles balises de script Converties en servlet lors de leur toute première invocation L'objectif principal consiste à simplifier la couche de présentation dynamique via une architecture multiniveaux

29 JSP Du java dans une page WWW !
... <I> <%= request.getParameter("titre") %> </I> Entre les balises JSP <% … %> On peut mettre des pages .jsp partout où on met des pages HTML Elles sont converties "au vol" en servlet par le moteur de JSP Du java dans une page WWW ! JSP combine le langage de marquage (HTML ou XML) avec des fragments de code Java, pour produire une page HTML dynamique. On peut mettre des pages .jsp partout où on met des pages HTML. Elles sont converties "au vol" en servlets En fait, sans le voir réellement, chaque page .jsp est une servlet (comme vous savez maintenant l ’écrire …) avec toute la partie HTML statique simplement renvoyée (écrite vers le flux de sortie) vers le browser client par la méthode « service ». Chaque page est automatiquement compilée en une servlet (par le moteur de JSP), a sa première demande, puis exécutée. Les développeurs appellent eux-même la première fois leurs nouvelles pages .jsp pour s ’assurer que le véritable premier utilisateur n ’attendra pas longtemps son accès a cause de la phase de compilation en servlets qui n ’aura pas été réalisée.

30 Un exemple simple <html><head><title>Un exemple de page JSP</title></head><body> <!-- définit les informations globales a la page --> language="java" %> <!-- Déclare la variable c --> <%! char c = 0; %> <!-- Scriplet (code java) %> <% for(int i = 0; i < 26; i++){ for(int j = 0; j < 26; j++){ c = (char)(0x41 + (26 - i + j)%26); %> <%= c %> <% } %> <br> <% } %> </body></html> Cet exemple génère les majuscules de l ’alphabet 26 fois et en change la première. <%= c %> génère la valeur de c.toString() dans la page HTML

31 Passons à la pratique La structure d'une page JSP est le subtil mélange d'une servlet et de balises HTML, auquel a été ajoute une pincée de code Java entre des balises <% et %> et un zeste de balises XML Balises JSP se divisent en trois catégories les éléments de script : permettent d'insérer du code Java dans une page JSP les directives : elles influencent la structure globale de la servlet issue de la conversion les actions : il s'agit de balises spéciales servant à modifier le comportement du code JSP durant son exécution On peut également créer ses propres balises !

32 Passons à la pratique Certaines règles générales s'appliquent aux pages JSP les balises JSP sont sensibles à la casse les directives et les éléments de script obéissent à une syntaxe qui ne repose pas sur XML (une syntaxe de type XML peut également être utilisée) les valeurs des attributs dans les balises apparaissent toujours entre guillemets les URLs présentes dans les pages JSP respectent les conventions de la servlet si une URL commence par /, nomme chemin relatif de contexte, elle est interprétée en fonction de l'application Web à laquelle la JSP appartient, sinon elle est interprétée en fonction du code JSP courant

33 Directives JSP Les directives JSP sont des messagers envoyés par le code JSP au conteneur JSP Elles servent à définir les valeurs globales, telles que les déclarations de classes, les méthodes à mettre en œuvre, le type de contenu produit... Elles ne produisent aucune sortie à envoyer au client La portée des directives concerne l'intégralité du fichier JSP Les directives commencent par une balise et finissent par %> La syntaxe générale est la suivante : nomdirective attribut="valeur" attribut="valeur" %>

34 Directives JSP On peut utiliser trois directives principales dans les pages JSP La directive page la directive include la directive taglib

35 Directives JSP La directive page
Elle est utilisée pour définir et manipuler un nombre important d'attributs des pages et qui influencent le fichier JSP dans sa totalité Elle sert également à communiquer ces attributs au conteneur La syntaxe générale de la directive page est la suivante : page ATTRIBUTS %> Elle peut par exemple contenir les imports des paquetages et classes nécessaires au code Java contenu, les attributs de session, le niveau de sécurité des threads...

36 La directive : page Valeurs possibles : <%@ page language="java"
page import="java.util.*, java.net.*" %> page contentType="text/plain" %> page session="true|false " %> page errorPage="pathToErrorPage" %> page isErrorPage="true|false" %> page … page language="java" indique au serveur le langage utilisé dans le fichier. Java est la seule syntaxe prise en charge pour le moment. page import="java.util.*, java.net.*" %> - idem à toute première section de programme Java, - à placer au début du fichier JSP page contentType="text/plain;charset=ISO " %> type MIME et jeu de caractères de la page JSP page session="true|false " %> si "true", la page peut accéder aux données de session page errorPage="pathToErrorPage" %> - chemin relatif de la page JSP pour les exceptions non gérées - isErrorPage doit etre à true

37 Directives JSP Exemple de directive page
page language="Java" import="java.rmi.*,java.util.*" session="true" buffer="12kb" autoFlush="true" info="Ma directive page" errorPage="error.jsp" isErrorPage="false" isThreadSafe="false" %> <html> <head> <title>Page de test de la directive page</title> </head> <body> <h1> Page de test de la directive page</h1> Bla bla bla... </body> </html>

38 Directives JSP La directive include
Elle ordonne au conteneur d'insérer le contenu de la ressource dans la page JSP courante, en l'imbriquant à la place de la directive La syntaxe de la directive include est la suivante : include file="nomfichier" %> Le fichier inclus peut être une ressource statique (tel qu'un fichier HTML) ou une autre page JSP Exemple : <html> <head> <title>Page de test 1 de la directive include</title> </head> <body> <h1> Page de test 1 de la directive include</h1> include file="/test.html" %> include file="/jspTest.jsp %> </body> </html>

39 Directives JSP La directive taglib
Elle permet à la page d'utiliser des extensions de balises (voir fin cours) Le conteneur exploite cette bibliothèque de balises afin de savoir ce qu'il doit faire lorsqu'il rencontre des balises personnalisées dans la page JSP La syntaxe de la directive taglib est la suivante : taglib uri="tagLibraryURI" prefix="tagPrefix" %> On ne le fera pas dans ce cours (manque de temps), mais ce mécanisme permet de créer des balises personnalisées qui correspondent en fait a des classes Java Les taglibs permettent de séparer la présentation du code de manière optimale

40 Eléments de script Les éléments de script permettent l'insertion dans la JSP de code Java, de déclarations de variables ou de méthodes, de scriptlets (code Java arbitraire) et d'expressions Déclarations Bloc de code Java dans une page JSP utilisé pour définir des variables et des méthodes de classe dans une servlet générée Initialisées lors de l'initialisation de la page JSP Portée de "classe" dans la servlet générée : accessible via la page JSP à d'autres déclarations, expressions et fragments de code Délimitée par <%! et %> et n'envoie rien dans le flux de sortie Scriptlets Bloc de code Java exécuté au cours du processus de traitement de la requête, et qui se trouve entre des balises <% et %> Peuvent produire une sortie vers le client Peuvent modifier les objets en interne à l'aide des méthodes

41 Eléments de script : les déclarations
<%! private int accessCount = 0; private int incrementCount() {return accessCount++;} %> ... <H2>Nombre et liste des articles</H2> Nombre d'articles : <%= incrementCount() %> définitions des méthodes et variables de classe à utiliser dans toute la page définit les méthodes jspInit() et jspDestroy()

42 Eléments de script : les scriptlets
<% code Java %> (scriplets) <% String nom = request.getParameter("nom"); ... out.println("Nom de l'utilisateur " + nom); %> c'est un bloc de code Java placé dans _jspService() de la servlet générée ayant accès : aux variables et beans déclarés ( <%! … %> ) aux objets implicites (voir plus loin) <% Java code %> (scriplets) Ce code est place dans la methode _jspService() de la servlet generee. Le code defini dans une scriplet a acces : - aux variables et aux composants Java (beans) declares, - une ribambelle d ’objets implicites, a partir de l ’environnement de la servlet comme : - request - response, ...

43 Eléments de script Expressions
Une expression est une notation courte d'une scriptlet qui renvoie la valeur d'une expression vers le client L'expression est évaluée lors du traitement de la requête HTTP, le résultat est converti en String puis il est affiché Délimitée par des balises <%= et %> Si le résultat de l'expression est un objet, la conversion est exécutée à l'aide de la méthode toString() de l'objet La syntaxe est la suivante : <%= expression Java à traiter %>

44 Eléments de script : les expressions
Il est <%= new java.util.Date() %> <P> et votre hostname est <%= request.getRemoteHost() %> permet d’intégrer des valeurs dans le code HTML ces valeurs sont évaluées, converties en chaînes de caractères et affichées les objets implicites (request, response, session, out, ...) disponibles <%= expression %> L ’expression ne termine pas par un ; car le moteur JSP la place dans un appel out.println().

45 Actions standard Les actions standard sont des balises qui affectent l'exécution de la page JSP et la réponse renvoyée au client Elles doivent être fournies par tous les conteneurs Une action standard est en réalité une balise incorporée dans une page JSP Au cours de la compilation de la servlet, le conteneur rencontre cette balise et la remplace par le code Java correspondant à la tache prédéfinie requise Par exemple, s'il rencontre une action include standard <jsp:include page="myJsp.jsp" flush="true" />

46 Actions standard Elles servent à offrir aux auteurs des pages JSP des fonctionnalités de base qu'ils peuvent exploiter afin d'exécuter des taches courantes Les types d'actions standard sont les suivants : <jsp:usebean> <jsp:setProperty> <jsp:getProperty> <jsp:param> <jsp:include> <jsp:forward> <jsp:plugin>

47 Actions standard <jsp:useBean>
Pour séparer le code de la présentation, il est conseille d'encapsuler le code dans un objet Java (un JavaBean), puis de l'instancier et de l'utiliser au sein de la page JSP <jsp:useBean> permet de créer ou de localiser une instance d'un bean donne, d'en définir la durée de vie... La syntaxe de l'action useBean est la suivante : <jsp:useBean id="name" scope="scopeName" beandetails /> ou beandetails est au choix class="className" class="className" type="typeName" beanName="beanName" type="typeName" type="typeName"

48 Actions standard <jsp:setProperty>
Utilisée pour fixer les propriétés d'un bean Il est possible de définir les propriétés d'un bean de plusieurs manières : au moment de la requête, à l'aide de l'objet request au moment de la requête, avec une expression évaluée à l'aide d'une chaîne spécifiée (ou codée physiquement) dans la page La syntaxe de l'action setProperty est la suivante : <jsp:setProperty name="beanName" propertydetails /> ou propertydetails est au choix : property="*" property="propertyName" property="propertyName" param="parameterName" property="propertyName" value="propertyValue"

49 Actions standard <jsp:getProperty>
Utilisée pour accéder les propriétés d'un bean Accède à la valeur d'une propriété, la convertit en String et l'envoie vers le flux de sortie, puis vers le client La syntaxe est la suivante : <jsp:getProperty name="name" property="propertyName"/> et les attributs sont les suivants : name : Nom de l'instance du bean property : Nom de la propriété a obtenir

50 Usebean et getProperty
Mécanisme très puissant ! <jsp:usebean id="name" (référence l'instance du composant) class="paquetage.class" (nom qualifié de la classe) scope="page|request|session|application" (portée) /> Pour lire une propriété du bean : <jsp:getProperty name="name" property="property" /> <jsp usebean id="name" : nom servant à référencer l'instance du composant dans la page D'autres balises utilisent name pour se référer à cet id class="package.class" : nom entièrement qualifié de la classe; inutile d'importer ces classes dans la directive page scope="page" : portée de l'objet PageContext; elle s'étend jusqu'à la fin de la page; l'état n'est pas stocké. "request" : l'instance du composant dure pendant la requête cllient "session" : le composant dure autant que la session; une référence est disponible par HttpSession.getValue(); ne pas utiliser si la directive de page session est déclarée comme false "application" : l'instance du composant est crée avec l'application et dure jusqu'à sa fin.

51 Usebean et setProperty
Pour modifier une propriété du bean : <jsp:setProperty name="name" property="property" value="value" /> property="*" /> Initialise tous les attributs de l ’objet name avec les paramètres HTTP du même nom En 2 lignes !

52 Exemple d'utilisation d'un bean
La page JSP : <html> ... <jsp:usebean id="test" class="test.SimpleBean" /> <jsp:setProperty name="test" property="message" value="Hello !!" /> <h1>Le message est : <i> <jsp:getProperty name="test" property="message" /> </i></h1>… </html>

53 Actions standard <jsp:param>
Permet de fournir d'autres balises contenant des informations complémentaires sous la forme de paires nom/valeur Elle est utilisée conjointement avec les actions include, forward et plugin La syntaxe est la suivante : <jsp:param name="paramName" value="paramValue"/> Les attributs disponibles sont les suivants : name : Clé associée a l'attribut value : valeur de l'attribut

54 Actions standard <jsp:include>
Permet l'insertion dans la page JSP courante, au moment du traitement de la requête, de ressources statiques ou dynamiques Même fonctionnement que le Dispatcher de servlets Une page incluse ne peut définir ne en-tête ni cookie La syntaxe est la suivante : <jsp:include page="URL" flush="true"> <jsp:param name="name" value="value"/> </jsp:include> Ou : URL : La ressource a inclure flush : toujours true ! Les paramètres passes dans les balises <jsp:param> sont accessibles a la ressource qui est incluse au travers l'objet request transmis

55 Actions standard <jsp:forward>
Permet le transfert de la requête vers une autre page JSP, une autre servlet ou une ressource statique La syntaxe est la suivante : <jsp:forward page="URL"> <jsp:param name="name" value="value"/> </jsp:forward> La ressource vers laquelle la requête est transférée doit se trouver dans le même contexte que la page JSP qui émet la requête Il s'agit d'une redirection cote serveur qui prend en compte des paramètres supplémentaires

56 Actions standard <jsp:plugin>
Utilisée dans les pages pour générer des balises HTML propres au navigateur client Cette action a pour conséquence de télécharger le plug-in Java par exemple, puis d'exécuter l'applet ou le composant JavaBean spécifié dans la balise S'accompagne parfois de deux balises supplémentaires : <jsp:params> afin de transmettre des paramètres supplémentaires a l'applet ou au JavaBean <jsp:fallback> afin de spécifier le contenu a afficher dans le navigateur client si le plug-in ne peut pas démarrer

57 Objets Implicites L'API servlet inclut des interfaces qui établissent des couches d'abstraction pratiques pour le developpeur HttpServletRequest, HttpSession... Ces interfaces représentent les données HTTP et fournit les méthodes appropriées pour les manipuler JSP propose certains objets implicites, reposant sur l'API Servlet Ces objets sont accessibles via des variables standard et sont automatiquement disponibles pour vos pages JSP sans que vous ayez besoin de rajouter du code

58 Objets Implicites Les objets implicites disponibles dans une page JSP sont les suivants : request : représente l'objet HttpServletRequest response : représente l'objet HttpServletResponse pageContext : point d'accès pour de nombreux attributs de page session : l'objet HttpSession application : contexte de servlet ServletContext out : le flux de sortie JspWriter (idem response.getWriter()) config : l'objet ServletConfig pour cette page page : instance de la classe de servlet d'implémentation qui traite la requête en cours

59 Quelques exemples d’actions
<jsp:include page="relative URL" flush="true" /> inclusion au moment où la page est servie, pas au moment où elle est traduite en servlet. <jsp:usebean id="name" class="package.class" /> permet d'instancier un bean depuis une page JSP. nécessite de connaître le mécanisme des beans... associé à <jsp:getProperty.../> et <jsp:setProperty.../> <jsp:forward page="/uneAutreURL" /> redirige vers une autre URL


Télécharger ppt "UV JSP JSP : Java Server Page"

Présentations similaires


Annonces Google