Cours-Gratuit
  • Accueil
  • Blog
  • Cours informatique
home icon Cours gratuits » Cours informatique » Cours programmation » Cours JAVA » Cours Framework JAVA

Cours Framework JSF perfectionnement

Cours Framework JSF perfectionnement
Participez au vote ☆☆☆☆☆★★★★★

JSF

(Java Server Faces)

EMSI - Université de Nice Sophia Antipolis

Richard Grin

Version O 2.25 – 4/11/18

Plan de ce cours

? Présentation de JSF

? Architecture des applications JSF

? Exemple de page JSF

? Backing bean et portée CDI

? Cycle de vie

? Fichiers de configuration

? Navigation

? PRG

? Messages d’erreur ou d’information

         R. Grin                                                           JSF

? ? ? ?

Événements

Ajax

JSF et HTML5

Ressources

page 2

Présentation de JSF

         R. Grin                                                           JSF                                       page 3

JSF

? Framework Java pour le développement d’applications Web

? Une page HTML vue par le client Web est représentée sur le serveur par des composants Java

? Ces composants Java sont décrits dans une page JSF (fichier au format XML)

         R. Grin                                                           JSF                                                           page 4

EL et backing bean

? EL (Expression Language) : langage utilisé pour représenter des données dynamiques ou des traitements à exécuter dans les pages JSF

? Les expressions EL sont encadrées par #{ }

? Une expression EL utilise le plus souvent un backing bean, classe Java lié à la page JSF :

? une propriété du backing bean peut représenter une donnée dynamique

? une méthode du backing bean peut représenter un traitement à exécuter

page 6


Exemple - page JSF form.xhtml

Espace de noms

<?xml version="1.0" encoding="UTF-8"?>

par défaut

<!DOCTYPE html>

<html xmlns=";      Espace de xmlns:h=";> noms JSF

<h:head> <title>Présentation</title> </h:head>

<h:body>

<h3>Présentation</h3>

<h:form>

Nom : <h:inputText value="#{}"/>

<h:commandButton value="Enregistrer" action="#{utilisateur.direHello()}"/>

</h:form>

</h:body>

Vous devinez comment cette page sera utilisée ?

</html>

R. Grin                                                           JSF                                                           page 7

Exemple - page JSF form.xhtml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html>

<html xmlns="; xmlns:h=";>

<h:head> <title>Présentation</title> </h:head>

<h:body>                                                utilisateur :               Propriété nom

                  <h3>Présentation</h3> nom backing bean       du backing bean

<h:form>

Nom : <h:inputText value="#{}"/> Formu         <h:commandButton value="Enregistrer" laire          action="#{utilisateur.direHello()}"/>

</h:form> Bouton soumet formulaire

               </h:body> par requête POST envoyée              Méthode direHello

        </html>                     au serveur                            du backing bean

       R. Grin                                                           JSF                                                               page 8

Principaux services rendus par JSF

? Conversion entre le texte de l’interface utilisateur et les valeurs Java du serveur

? Validation des données saisies par l’utilisateur

? Automatisation de l’affichage des messages d’erreur si problèmes de conversion ou validation

? Internationalisation

? Support d’Ajax sans programmation

? Templates graphiques

? Librairies de composants

R. Grin                                                           JSF                                                          page 13

Les traitements

? Séparation très nette entre

? les pages JSF

? les traitements à exécuter

? Même les traitements directement liés à l’interface utilisateur sont effectués en dehors de la page JSF, par du code Java (backing bean)

R. Grin                                                           JSF                                                          page 14

Code d’un backing bean

? Propriétés pour valeurs à afficher ou saisies par l’utilisateur :

<h:inputText value="#{}"/> setter et getter utilisés en interne

Architecture des applications JSF

R. Grin                                                           JSF                                                           page 15

Répartition des tâches

? Pages JSF pour l’interface avec l’utilisateur ; ne contiennent aucun traitement

? Backing beans pour les traitements liés directement à l’interface utilisateur

? Backing beans font appel à des EJB ou POJO pour les autres traitements (traitements métier, accès aux sources de données,…)

? Accès aux bases de données utilisent souvent JPA et donc les classes entités

R. Grin                                                           JSF                                                           page 16

? Traitements lancés par l’utilisateur, par un clic bouton par exemple :

<h:commandButton value="Enregistrer" action="#{utilisateur.direHello()}"/>

? Expression qui indique si un composant doit être affiché :

<h:inputText value="#{bean.client.pourcentageRemise}" rendered="#{bean.client.bonClient}" />

page 18


Servlet « Faces »

? Le servlet JSF gère le cycle de vie JSF, fondamental pour JSF

? Ce servlet est fourni par JSF et caché au développeur

? Un mapping indique les requêtes qui seront traitées par ce servlet ; par défaut celles avec les URLs /faces/*, *.jsf, *.faces , *.xhtml, qui correspondent toujours à un fichier *.xhtml (par exemple correspond à page.xhtml)

R. Grin                                                           JSF                                                          page 19

Template

? Les pages d’un site Web respectent souvent une charte graphique

? L’aspect commun aux pages est défini dans un fichier XHTML à part, appelé template

Convertisseurs et validateurs

? Les convertisseurs peuvent être fournis

? par JSF (convertisseur standard)

? par une classe (balise <f:converter> ou attribut converter)

? par une propriété d’un backing bean (attribut converter)

? par un convertisseur par défaut pour un type ? Les validateurs peuvent être fournis

? par JSF

? par une classe (balise <f:validator>) ? par une méthode (attribut validator)

page 23

Template avec 2 parties variables

<ui:insert>, titre et contenu

R. Grin

Conversion et validation

? Les données saisies dans les formulaires HTML sont des chaînes de caractères

? Il faut les convertir dans le bon type Java (celui de la propriété du backing bean) :

<h:inputText id="age" value="#{}" >

? Elles doivent être validées (18 < age < 70 par exemple) avant d’exécuter les traitements qui les utilisent

         R. Grin                                                           JSF                                                         page 22

? Un template contient des parties « variables » : <ui:insert name="header"/>

? Une page JSF qui utilise ce template (page cliente du template) a l’aspect défini par le template ; elle définit les parties variables :

<ui:define name="header"> </ui:define>

                                                                                                                            R. Grin                                                           JSF                                                          page 20

Exemple de convertisseur donné par une propriété du backing bean

@EJB            Qui peut expliquer ? private DiscountFacadeEjb ejb;

public Converter<Discount> getDiscountConverter() {

return new Converter<Discount>() {

Exemple plus complet de page JSF

page 29

Validation des beans

? Les champs d’une classe (backing bean ou entité JPA) peuvent être annotés pour définir une contrainte à respecter :

@Min(18) @Max(70) private int age;

         R. Grin                                                           JSF

page 27

Composants des pages JSF

? Nombreux composants standards qui correspondent aux balises HTML :

? saisie des données <h:inputText>

? listes déroulantes <h:selectOneMenu>

? boutons <h:button> ou <h:commandButton>

? tables <h:table>

? …

? Pour améliorer ces composants ou pour en avoir de nouveaux le développeur peut

? utiliser des bibliothèques de composants

? créer ses propres composants

         R. Grin                                                           JSF                                                         page 28

@Override public DiscountCode getAsObject(

FacesContext ctx, UIComponent cmp, String val) { return ejb.findById(val);

}                                                                                                   Utilisé dans TP 1.

        @Override                                                                               Pour faire quoi ?

public String getAsString(

FacesContext ctx, UIComponent cmp, Discount d) { return d.getDiscountCode();

}}; }

R. Grin                                                             JSF                                                         page 25


CSS et JSF – fichier des styles

? Utiliser <h:outputStylesheet> à la place de <link rel="stylesheet"> :

<h:outputStylesheet name="" />

? JSF va chercher le fichier dans le répertoire resources placé sous la racine des pages Web ; dans pour l’exemple

R. Grin                                                           JSF                                                        page 35

CSS et JSF – style d’un composant

? Pour donner du style à un composant JSF, utiliser l’attribut styleClass (ou style pour du CSS

intégré) ou un des attributs particuliers à un composant (comme columnClasses de

<h:panelGrid>)

? Attention si vous utilisez #id dans le fichier CSS : l’id d’un composant JSF ne correspond pas à l’id du composant HTML envoyé au client

R. Grin                                                           JSF                                                        page 36

Commentaires

? Par défaut les commentaires HTML (<!-- -->) ne fonctionnent pas bien pour JSF, mais on peut configurer pour qu’ils soient pris en compte

? On peut aussi entourer les composants que l’on veut enlever temporairement par la balise

<ui:remove>

         R. Grin                                                           JSF                                                         page 37

Backing bean et portée CDI (scope)

         R. Grin                                                           JSF                                                         page 38

Backing bean

? Backing bean géré par CDI, annoté par @Named

? (Ne pas utiliser les beans gérés par JSF, annotés par @ManagedBean !)

? Initialiser les ressources injectées dans une méthode annotée par @PostConstruct, pas dans un constructeur (il existe aussi

@PreDestroy pour « faire le ménage » avant la suppression du bean) Déjà vu pour quel autre

composant ?

         R. Grin                                                           JSF                                                         page 39

Exemples

? Ce bean sera désigné par employeBean :

@Named

@RequestScoped

public class EmployeBean { … }

? Celui-ci sera désigné par employe :

@Named("employe") @RequestScoped public class EmployeBean { … }

         R. Grin                                                           JSF

page 40

Bean géré

? Quand une page JSF désigne un bean, par exemple #{} le

container CDI regarde s’il existe un bean du même type dans la portée

? Si c’est le cas, le bean existant est utilisé par la page JSF

? Sinon un nouveau bean est créé par le container et utilisé par la page JSF

         R. Grin                                                           JSF                                                         page 41

getter

? Quand une page JSF utilise une propriété d’un backing bean, le getter de la propriété peut être appelé plusieurs fois

? Un getter ne doit donc pas exécuter à chaque appel un code coûteux, tel qu’un accès à une base de données

         R. Grin                                                           JSF                                                         page 42

Utilité de la portée

? Détermine la durée de vie du backing bean

? Si la portée est la session, il va durer jusqu’à la fin de la session de travail de l’utilisateur ; si une autre expression EL y fait référence pendant la même session, c’est le même bean qui sera utilisé

? On peut ainsi conserver des informations entre 2 requêtes, 2 pages ou, plus généralement, 2 traitements

? Le développeur doit choisir la bonne portée, au moins pour ne pas encombrer la mémoire du serveur

  R. Grin                                                           JSF                                                          page 44

Rappel des portées CDI

? Dependent : (portée par défaut) nouvel objet créé à chaque référence ; l’objet est supprimé quand l’objet dans lequel il est injecté est supprimé

? RequestScoped : requête HTTP

? ViewScoped : associé à une vue (page JSF)

? FlowScoped : associé à un ensemble de vues

? ConversationScoped : début et fin par code Java

? SessionScoped : session de travail de l’utilisateur

? ApplicationScoped : durée de vie de l’application ; partagé entre tous les utilisateurs

         R. Grin                 JSF                                 page 45

Serializable

? Les backing beans qui ont une autre portée que RequestScoped et Dependent doivent implémenter Serializable car ils peuvent être retirés temporairement de la mémoire centrale par le container

         R. Grin                                                           JSF                                                         page 46

2 types de portée

? JSF a aussi ses portées qui étaient associées à l’ancienne annotation @ManagedBean (deprecated et remplacée par @Named) mais il faut utiliser les portées CDI

? Attention à importer le bon paquetage

? Ne jamais utiliser les portées du paquetage !

         R. Grin                 JSF                                 page 47

Le cycle de vie

         R. Grin                                                           JSF                                                         page 48

? Indispensable de bien comprendre tout le processus qui se déroule entre

? la soumission d’un formulaire par l’utilisateur

? la réponse du serveur sous la forme d’une page HTML

R. Grin                                                           JSF                                                          page 49

Simple demande d’une page

? Étudions tout d’abord le cas simple d’une requête HTTP GET d’un client qui demande une page JSF, sans passer de paramètres dans la requête

         R. Grin                                                           JSF                                                         page 51

Cycle de vie simplifié

? La phase « Restore View » construit une vue vide

(ne contient aucun composant Java)

? La phase « Apply Request Values » s’aperçoit qu’il n’y a pas de paramètres dans la requête

? Le cycle de vie avance donc à la dernière phase

« Render Response » dans laquelle la vue de la page JSF demandée est créée, et codée en une

page HTML envoyée au client

         R. Grin                                                           JSF

Traitement d’un formulaire

? Etudions comment est traitée une requête HTTP POST générée par la soumission d’un formulaire d’une page JSF

? Sur le poste client, l’utilisateur a saisi des valeurs dans ce formulaire

? Ces valeurs sont mises en paramètres de la requête POST envoyée au serveur Web

? Tout le cycle de vie se déroule sur le serveur

         R. Grin                                                           JSF                                                         page 53

Phase de restauration de la vue

? La vue qui correspond à la page qui contient le formulaire est restaurée (phase « Restore View »)

      R. Grin                                                           JSF                                                          page 55

Phase d’application des paramètres

? Les valeurs des paramètres de la requête HTTP (saisies par l’utilisateur dans le formulaire) sont attribuées aux composants Java de la vue : phase « Apply Request Values »

? Par exemple, si l’utilisateur a saisi un âge dans un composant <h:inputText> du formulaire HTML, le composant Java associé met ce nom dans une variable interne

      R. Grin                                                           JSF                                                          page 57

Phase de validation

? Les expressions EL sont utilisées pour savoir dans quelles propriétés Java mettre les valeurs récupérées à l’étape précédente :

<h:inputText value="#{}" />

? Les données sont converties dans le type Java et ensuite validées pour voir si elles respectent les contraintes indiquées dans la page JSF et le bean

? Si une conversion ou validation échoue, la phase suivante sera la phase « Rendu de la réponse » qui retourne le formulaire avec tous les messages d’erreur

      R. Grin                                                           JSF                                                          page 59

Validation sur le client HTTP

? Possible de valider avec une fonction JavaScript par une balise JSF personnalisée                Intérêt ?

? Pour cela il est plus simple de s’appuyer sur une bibliothèque de composants JSF qui valide par

JavaScript, plutôt que d’écrire sa propre validation JavaScript

? Attention, ne remplace pas une validation sur le serveur Pourquoi?

      R. Grin                                                           JSF                                                          page 60

Phase de mise à jour du modèle

? Toutes les données ont été validées ; elles peuvent être mises dans les propriétés des backing beans associées (expressions EL) :

<h:inputText id="nom" value="#{}" />

         R. Grin                 JSF                                 page 61

         R. Grin                                                           JSF                                                         page 62

Phase d’invocation de l’application

? Maintenant que les données sont enregistrées dans les backing beans, l’action associée au bouton ou au lien cliqué par l’utilisateur peut être lancée ; une méthode des backing beans est exécutée :

<h:commandButton

action="#{inscriptionBean.confirmer}" />

? La valeur de retour de cette méthode détermine la prochaine page à afficher (navigation)

R. Grin                                                           JSF                                                         page 64

Phase de rendu de la réponse

? La page déterminée par la valeur retour de la méthode « action » est codée en HTML et envoyée vers le client HTTP

         R. Grin                                                           JSF                                                         page 66

Cycle de vie avec une requête GET

? Si l’URL de la requête contient des paramètres http://serveur/appli/adresse?p1=v1&p2=v2 et si la page JSF demandée contient des paramètres de vue (étudiés plus loin) pour ranger ces valeurs dans un backing bean, le cycle de vie complet est exécuté

? Comme si les valeurs des paramètres de la requête avaient été saisies par un utilisateur dans un formulaire soumis avec une méthode POST

         R. Grin                                                           JSF                                                         page 67

Sauter des phases

? Il est quelquefois indispensable de sauter des phases du cycle de vie

? Il est possible de sauter toutes les phases restantes, par exemple si on a déjà généré une réponse sous le forme d’un fichier PDF ; la méthode FacesContext.responseComplete() est faite pour cela

? L’attribut « immediate="true" » permet aussi de sauter des phases pour certains composants mais son intérêt est faible depuis l’intégration d’Ajax à

JSF

         R. Grin                                                           JSF                                                         page 68

Fichiers de configuration

         R. Grin                                                           JSF                                                         page 69

Exemple de (1/2)

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.1" xmlns=";

xmlns:xsi="; xsi:schemaLocation="

">

<context-param>

<param-name>javax.faces.PROJECT_STAGE</param-name>

<param-value>Development</param-value>

</context-param>

Production

pour livrer au client

         R. Grin                                                           JSF                                                         page 70

Exemple de (2/2)

<session-config>

<session-timeout>30</session-timeout>

</session-config>

<welcome-file-list>

<welcome-file>faces/index.xhtml</welcome-file>

</welcome-file-list>

</web-app>

         R. Grin                                                           JSF

page 71

Phase de projet

? Attention, la phase de projet Development ajoute automatiquement les messages d’erreurs, même s’il n’y a aucun composant pour les messages dans la page (<h:message> ou

<h:messages>)

? Ne pas oublier de mettre ces composants dans la page pour que l’utilisateur voie les messages quand l’application sera enproduction

         R. Grin                                                           JSF                                                         page 72

? Configuration pour CDI (optionnel)

? Sous WEB-INF si fichier WAR ou sous META-INF sinon

R. Grin                                                           JSF                                                          page 73

faces-config

? : configuration pour JSF

? Par exemple pour indiquer des fichiers de textes pour l’internationalisation (<resource-bundle>) ou pour donner des règles de navigation

R. Grin                                                           JSF                                                   JSF - page 74

Navigation

R. Grin                                                           JSF                                                          page 75

Navigation dans JSF

? Navigation = affichage d’une nouvelle page

? Composants JSF standards pour la navigation :

<h:commandButton>, <h:button>,

<h:commandLink>, <h:link>,

<h:outputLink>

? <h:commandButton> et <h:commandLink> doivent être dans une balise <h:form> ; ils soumettent le formulaire

? Les autres composants peuvent ne pas être dans un formulaire et, s’ils le sont, ils ne le soumettent pas

R. Grin                                                           JSF                                                          page 76

POST ou GET

? <h:commandButton> et <h:commandLink> soumettent le formulaire par une requête POST et affichent la page indiquée par l’attribut action :

<h:commandButton value="Voir liste" action="liste.xhtml" />

? <h:button> et <h:link> lancent une requête GET et affichent la page indiquée par l’attribut outcome :

<h:link value="Voir les notes"

outcome="/notes/voirNotes" />

? <h:outputLink> lance une requête GET et affiche la page indiquée par l’attribut value ; la page peut être en dehors de l’application

R. Grin                                                           JSF                                                          page 77

Recommandation

? Requête GET si on veut juste afficher une page ; par exemple afficher la liste de tous les clients

? Requête POST si l’utilisateur a saisi des données qu’on veut enregistrer sur le serveur ; par exemple si l’utilisateur a modifié le nom d’un client

R. Grin                                                           JSF                                                          page 78

Adresse affichée par le navigateur

? Avec une requête POST, le navigateur affiche l’URL du formulaire qui vient d’être soumis, alors que la nouvelle page est affichée ;

si on veut voir le bon URL, il faut ajouter une redirection

? Avec <h:button> et <h:link> le navigateur affiche le bon URL

R. Grin                                                           JSF                                                          page 79

Navigation statique et dynamique

? La valeur de l’attribut action qui détermine la nouvelle page peut être

? définie « en dur » au moment de l’écriture de l’application ; la navigation est statique

? définie par la valeur retournée par une méthode  Java ; la navigation est dynamique

R. Grin                                                           JSF                                                          page 81

Navigation déclarative ou implicite

? Si la valeur qui détermine la nouvelle page correspond à une règle de navigation, la règle détermine la prochaine page à afficher ; c’est la navigation déclarative

? Sinon c’est la navigation implicite (ce qu’on a vu jusqu’à maintenant)

R. Grin                                                           JSF                                                         page 84

Exemple de règle de navigation

? Règle de navigation dans :

<navigation-rule>

<from-view-id>page1.xhtml</from-view-id>

<navigation-case>

<from-outcome>ok</from-outcome>

<to-view-id>/succes.xhtml</to-view-id>

</navigation-case>

<navigation-case>

<from-outcome>ko</from-outcome>

<to-view-id>/echec.xhtml</to-view-id>

</navigation-case>

</navigation-rule> ? Dans page1.xhtml :

<h:commandButton action="ok" value="Valider" />

Page suivante si clic sur bouton ? /succes.xhtml

R. Grin                                                           JSF                                                          page 85

Redirection

? Dans le cas d’une navigation statique, ajouter

?faces-redirect=true à l’URL de la page à afficher :

action="page2?faces-redirect=true"

? Dans le cas d’une navigation dynamique, ajouter à la valeur retournée par la méthode :

return "page2?faces-redirect=true";

         R. Grin                                                           JSF                                                         page 87

? Exercices 1 et 2 du TP 2 (modèle PRG)

         R. Grin                                                           JSF

page 88

R. Grin

PRG

    JSF                                                         page 89

Problèmes avec POST

? Un formulaire est dans une page P1 ; la soumission du formulaire par une requête POST affiche une page P2 en réponse ? 2 problèmes :

? quand P2 est affichée en réponse à la requête POST, le navigateur affiche l’adresse de P1

? un refresh de P2 après le POST soumet à nouveau le formulaire

         R. Grin                                                           JSF                                                         page 90

La raison du problème d’URL

? C’est JSF qui dirige vers la nouvelle page (à la fin de la phase « Invoke Application »)

? Le navigateur n’en a pas connaissance ; il continue à afficher l’adresse du formulaire

         R. Grin                                                           JSF                                                         page 91

Refreshou reloadd’une page

? Si l’utilisateur demande un refresh de la page, c’est qu’il veut la dernière version de l’information affichée dans la page

? Le navigateur envoie donc à nouveau la requête qui a permis d’obtenir la page

? Si la page a été affichée en réponse à une requête POST, le navigateur relance donc la requête POST avec les mêmes paramètres, ce qui correspond à une nouvelle soumission du formulaire

         R. Grin                                                           JSF                                                         page 92

Les conséquences du problème

? Impossible de garder un marque-page pour la page affichée après un POST

? Commande ou paiement involontaire dû à une soumission multiple d’un formulaire

Qu’est-ce qui est le plus grave ?

         R. Grin                                                           JSF

page 93

La solution :

Post – Redirect - Get (PRG)

? Le modèle Post – Redirect - Get :

? Ne jamais montrer une page en réponse à un

POST

? Charger les pages uniquement avec des GET

? Utiliser la redirection pour passer de POST à

GET

         R. Grin                                                           JSF                                                         page 94


Problèmes de PRG

? La redirection peut poser un problème :

? Informations conservées dans la requête du POST ne sont plus disponibles après la redirection

? Messages de succès ou d’information, générés par programmation, sont conservés le temps d’une requête et donc n’apparaissent plus après une redirection

R. Grin                                                             JSF                                                          page 97

Portée session ?

? Une des solutions est de ranger les informations dans la session plutôt que dans la requête

? Mais cette solution est mauvaise car elle peut conduire à une session trop encombrée ou à d’autres problèmes (en particulier session ne tient pas compte des onglets des navigateurs)

R. Grin                                                             JSF                                                          page 98

Solutions

? JSF offre des possibilités pour conserver les informations plus longtemps que la requête, sans passer en portée session

? Le plus intéressant est d’utiliser les paramètres de vue (permet de rester en portée « requête »)

R. Grin                                                             JSF                                                          page 99

Paramètres de vue

? Une requête GET avec 2 paramètres nom et age :

;age=23

? Avec des paramètres de vue on peut récupérer les valeurs « Bob » et « 23 » dans des propriétés d’un backing bean

? Un paramètre de vue est créé par une balise

<f:viewParam> placée à l’intérieur d’une balise

<f:metadata> dans la page demandée par GET

(page2.xhtml pour l’exemple)

R. Grin                                                             JSF                                                        page 100

Placement de <f:metadata>

? Doit être au « top level », pas dans une autre balise

? Si un template est utilisé, il ne faut pas mettre <f:metadata> dans le template ; il faut le mettre dans le client du template

page 102

Exemple

Requête GET

? Dans page2.xhtml (juste avant <h:head>) :

<f:metadata>

<f:viewParam name="nom" value="#{bean.p1}" />

</f:metadata>

? Bob sera mis dans la propriété  p1 de bean, avant l’affichage de la page

? Dans <f:viewParam>, comme dans

<h:inputText>, on peut ajouter un convertisseur, un validateur ou un attribut required

page 101

<f:viewAction>

? Balise d’une page demandée par GET ; doit être placée à l’intérieur de <f:metadata> ? Exécute une méthode d’un backing bean

? Exemple :

<f:viewAction action="#{bean.m()}"/> ? Cette méthode est exécutée

? après l’enregistrement par <f:viewParam> des valeurs des paramètres de la requête GET dans un backing bean

? avant l’affichage de la page

         R. Grin                 JSF                                                page 103

Exemple d’utilisation

? Soit une requête GET http://…/employe.xhtml?id=12

? Un paramètre de vue de la page employe.xhtml récupère la valeur de l’id de la requête (12) dans la propriété id d’un backing bean

? L’action de <f:viewAction> récupère dans la base de données l’employé qui a l’id 12 et le met dans une propriété employe (type Employe) du backing bean

? Les informations sur l’employé sont ensuite affichées dans la page employe.xhtml, par exemple par

#{}

         R. Grin                                                           JSF                                                        page 104

Dans les TPs

? Vous vous souvenez quand on a utilisé <f:viewAction> dans le TP 1 ?

? Ce procédé sera encore utilisé dans le TP 3 ? Une autre façon de faire :

? utiliser un paramètre de vue

? avec un convertisseur dans <f:viewParam> pour transformer l’id en employé (remplace l’utilisation de <f:viewAction>)

? Vous vous souvenez quand on a utilisé un convertisseur ?

R. Grin                                                           JSF                                                        page 106

includeViewParams (1/2)

? Cet attribut peut être ajouté à tout lien vers une page qui contient des paramètres de vue :

<h:commandButton value=… action="page2?faces-redirect=true&amp; includeViewParams=true" />

? includeViewParams=true signifie « inclure dans le lien les paramètres qui correspondent aux paramètres de vue de la page de destination, avec les valeurs définies par l’expression EL du paramètre de vue »

         R. Grin                 JSF                                                page 107

includeViewParams (2/2)

? Si l’action désigne une méthode, il faut ajouter « includeViewParams=true » dans la valeur retournée par la méthode :

return"page2?faces-redirect=true&amp; includeViewParams=true";

         R. Grin                                                           JSF                                                        page 108

Utilité de includeViewParams

? Si page1 et page 2 utilisent des backing beans de portée requête de la même classe, ça permet de passer des valeurs du backing bean de page1 dans le backing bean de page2, après une redirection

? Le 1er bean ne dure que le temps de la requête

POST ; les valeurs des paramètres de vue (donc du 1er bean) sont passés dans la requête GET de redirection

? Le 2ème bean utilisé par la page d’arrivée met ces valeurs dans ses propriétés (grâce aux paramètres de vue)

R. Grin                                                           JSF                                                         page 109

                                                                                                                                                             Exemple      La valeur 5 a été passée 

de la 1ère à la 2ème

? page2.xhtml (backing bean bean) :instance de Bean

<f:viewParam name="n1" value="#{bean.p1}" />

? Lien de page1.xhtml (backing bean bean) :

<h:commandButton value=… action="page2?faces-redirect=true

&amp;includeViewParams=true" />

? Supposons que bean.p1 = 5 au départ de la requête, alors la requête GET aura le paramètre

« n1="#{bean.p1}" » donc « n1=5 »

? En arrivant dans page2.xhtml, la valeur 5 sera donc mise dans la propriété bean.p1

                                                                                                                          R. Grin                                                           JSF                                                            page 110

includeViewParams avec GET

? Avec un composant « GET » comme <h:link>, il faut utiliser l’attribut includeViewParams :

<h:link outcome="page"

includeViewParams="true" >

         R. Grin                                                           JSF page 111

Donner une valeur à un paramètre (1/2)

? Plusieurs autres façons de donner une valeur à un paramètre de requête GET :

? <h:link outcome="page?p1=4&amp;p2='bibi'" … >

<h:link outcome="page?p1=#{ + 2}" … >

?<h:link outcome="page" …>

<f:param name="p1" value="4"/> </h:link>

         R. Grin                                                           JSF                                                        page 112

Messages après redirection

? Un message d’information ou de succès généré par programmation peut être affiché après une redirection en utilisant la classe Flash (voir section suivante)

page 114

? Finir TP 2

? TP 3 (templates)

? Étudier la suite de ce support seul

         R. Grin                                                           JSF

page 115

Messages d’erreur ou d’information / de succès

         R. Grin                                                           JSF                                                        page 116

Cas d’utilisation

? Les conversions et validations peuvent conduire à l’affichage de messages d’erreur

? Lorsqu’une action s’est bien déroulée il faut le signaler à l’utilisateur par un message d’information / de succès

         R. Grin                                                           JSF                                                        page 117

Affichage des messages

? <h:messages> indique un emplacement de la page où sont affichés tous les messages

? <h:message> indique un emplacement pour afficher un message pour un seul composant identifié par l’attribut for

? Ces 2 balises ont de nombreux attributs

         R. Grin                                                           JSF                                                        page 118

Format d’affichage des messages

? Les attributs styleClass et style indiquent un style CSS pour affichage des messages

? D’autres attributs définissent un style lié à la sévérité du message (errorStyle, errorClass, infoStyle, infoClass,…)

         R. Grin                                                           JSF                                                        page 119

Exemples

? Messages de sévérité « ERROR » affichés avec la classe CSS « erreur » et messages de sévérité « INFO » affichés en vert et caractères gras

<h:messages errorClass="erreur" infoStyle="color:green;font-weight:bold;"/>

? <h:messages globalOnly="true"/>

affiche la liste des messages qui ne sont pas liés à un composant particulier

? <h:message for="nom" />

? <h:message for="nom" showSummary="true" showDetail="false" />

         R. Grin                                                           JSF                                                        page 120

Messages standards

? Les convertisseurs et validateurs standards produisent des messages d’erreur standards

? Les attributs des composants standards requiredMessage, converterMessage ou validatorMessage permettent de modifier ces messages

? Exemple :

<h:inputText id="nom" required="true" requiredMessage="Le nom est requis"/>

         R. Grin                                                           JSF                                                        page 121

Améliorer les messages standards

? Un message d’erreur peut comporter l’identifiant du composant concerné par l’erreur

? Pour rendre les messages plus clairs, il faut donner des identifiants significatifs (attribut id) aux formulaires et aux composants pour éviter les

« j_idt6:j_idt8 » dans les messages

? On peut aussi utiliser l’attribut label des composants ; ce label sera utilisé pour désigner le composant dans les messages

         R. Grin                                                           JSF                                                        page 122

Messages personnalisés

? Les convertisseurs et validateurs personnalisés permettent aussi d’afficher facilement des messages d’erreur

? S’ils ne peuvent être utilisés (par exemple validation qui englobe plusieurs composants) ou pour afficher un message de succès, le développeur peut ajouter ses messages dans les pages JSF par programmation Java

? Les transparents suivants étudient les classes et méthodes Java utilisées pour afficher ces messages

         R. Grin                                                           JSF                                                        page 123

Classe FacesMessage

? La classe FacesMessage du paquetage javax.faces.application représente un message affiché par <h:messages> ou

<h:message>

? Propriétés d’un message :

? sévérité (SEVERITY_FATAL, SEVERITY_ERROR,

SEVERITY_WARN, SEVERITY_INFO de la classe interne Severity)

? message détaillé

? message résumé

         R. Grin                                                           JSF                                                        page 124

Faire afficher son propre message

? Il suffit de passer une instance de FacesMessage à la méthode addMessage de FacesContext pour que le message soit affiché par les

<h:messages> ou <h:message> ? addMessage a 2 paramètres :

? id client du composant avec lequel le message est associé (de type String ; null si le message n’est pas attaché à un client particulier) ? Le message (classe FacesMessage)

page 125

Message de validation ou conversion

? Quand il y a une erreur dans un convertisseur ou un validateur, le code doit lancer une exception

(ConverterException ou ValidatorException)

et c’est le message passé au constructeur de l’exception qui est affiché

? Pas besoin de préciser le composant associé au message puisque c’est celui qui est validé

    R. Grin                                                           JSF                                                        page 128

Id client d’un composant

? Si on veut associer un message à un composant et qu’on n’est pas dans un convertisseur ou un validateur il faut trouver l’id client du composant

? Exemple de désignation d’un composant : si le composant a l’id « montant » dans le formulaire d’id « transfert », l’id du composant à passer

en 1er paramètre de addMessage est

« transfert:montant »

R. Grin                                                           JSF                                                        page 130

Identificateur « client »

? Pas toujours facile de trouver les id « client »

? Regarder le code HTML généré aide

? Identificateur client composé de plusieurs niveaux, avec le séparateur « : » ; par exemple,

« formulaire:j_idt41 »

? Pour faciliter, donner des ids aux composants (y compris composants englobants) et/ou utiliser l’attribut prependId="false" pour les formulaires qui les contiennent

? Identificateur doit exister dans la page HTML générée

(attention aux rendered="false")

         R. Grin                 JSF                              page 131

Message après redirection

? Puisqu’un message ne dure qu’une seule requête, il ne s’affichera pas après une redirection

? Si on veut qu’il s’affiche, il faut un code un peu plus complexe qui utilise la classe Flash

         R. Grin                                                           JSF                                                        page 132


Messages internationalisés

? L’internationalisation d’une application n’est pas difficile mais pas étudiée dans ce cours d’introduction

? Juste une petite difficulté pour faire afficher des messages créés par programmation, qui dépendent de la langue il faut récupérer le ResourceBundle qui contient les textes en différentes langues :

ResourceBundle textes =

ResourceBundle.getBundle(CHEMIN_BUNDLE); texte = textes.getString(nomPropTexte);

R. Grin                                                           JSF                                                        page 134

Événements

         R. Grin                 JSF                                page 135

Types d’événements

? 2 grands types d’événements :

? Généré par une action de l’utilisateur

(de type « application »)

? Généré à un moment du cycle de vie

(de type « lifecycle »)

         R. Grin                                                           JSF

page 136

Événements « application »

? ValueChangeEvent : valeur d’un composant modifiée par l’utilisateur (champ de saisie de

texte, menu, liste déroulante,…) ; liés aux composants tels que <h:selectOneMenu> ou <h:inputText>

? ActionEvent : clic sur un bouton ou un lien ; liés aux composants tels que <h:commandButton> ou <h:commandLink>

         R. Grin                 JSF                                page 137

Écouteur

? Les événements sont traités par des écouteurs,

? méthodes (attribut xxxListener)

? ou classe (sous-balise <f:xxxListener>)

         R. Grin                                                           JSF                                                        page 138

R. Grin

Ajax

    JSF                                                         page 141

Ajax

? Asynchronous Javascript and XML

? Une requête Ajax envoyée par le client est lancée « en arrière-plan » ; l’utilisateur peut continuer à travailler avec la page en cours

? La réponse du serveur à la requête ne modifie qu’une partie de la page en cours

         R. Grin                                                           JSF                                                        page 142

<f:ajax>

? Ajoute des fonctionnalités « Ajax » au composant

JSF dans lequel il est inclus

? Un événement déclencheur sur ce composant provoque l’envoi d’une requête Ajax au serveur sans attendre la soumission du formulaire

? Par exemple, une liste déroulante peut envoyer une requête Ajax quand l’utilisateur fait un nouveau choix ; la réponse du serveur ne mettra à jour qu’une partie de la page, par exemple une 2ème liste déroulante dont les valeurs dépendent du choix fait par l’utilisateur dans la 1ère liste

         R. Grin                                                           JSF                                                        page 143

<f:ajax> - les attributs

? event : événement déclencheur de la requête ; valeur par défaut dépend du composant, par exemple, valueChange pour les <h:inputText> ou action pour les <h:commandButton>

? execute : composants pris en compte pour l’envoi de la requête (espace séparateur) ; valeur par défaut @this, le composant qui contient <f:ajax>

? render : composants mis à jour au moment de la réponse du serveur (espace séparateur) ; valeur par défaut @none

         R. Grin                                                           JSF                                                        page 144

Identificateurs « client »

? Utilisés dans les attributs execute et surtout render

? Revoir section « Messages d’erreur ou d’information »

         R. Grin                                                           JSF                                                        page 147

Mélange d’Ajax et de requête normale

? Quand un champ de saisie lance une requête

Ajax, et que l’utilisateur appuie sur la touche [Entrée] après avoir saisi la valeur, un message d’avertissement indique qu’une requête Ajax a été mélangée avec une requête « normale » (l’appui sur la touche [Entrée] déclenche la soumission du formulaire en même temps que l’action « Ajax »)

? Pour ne plus avoir cet avertissement, il suffit de passer le bouton de soumission en Ajax :

<h:commandButton …><f:ajax execute="@form" render="@form"/></h:commandButton>

         R. Grin                                                           JSF                                                        page 148

Listener

? L’attribut listener de <f:ajax> désigne une méthode qui est appelée quand l’événement déclencheur de l’appel Ajax survient :

<f:ajax event="keyup" render="table" listener="#{bb.m}"

? Le plus souvent la méthode modifie le backing bean utilisé par la page, ce qui modifie la page

R. Grin                                                           JSF                                                        page 149

Exemple d’utilisation

? Un écouteur peut récupérer

? un client à partir d’un id saisi par l’utilisateur

? tous les noms qui commencent par les caractères tapés par l’utilisateur sont affichés comme suggestion (complétion de nom)

         R. Grin                                                           JSF                                                        page 151

JSF et HTML5

         R. Grin                                                           JSF                                                        page 152

Pages HTML5

? Les pages HTML générées par JSF sont maintenant déclarées comme des documents

HTML5 avec

<DOCTYPE html>

         R. Grin                                                           JSF                                                        page 153

Composants HTML5

? Avant JSF 2.2, pour profiter d’un nouveau composant HTML dans JSF il fallait écrire un composant JSF

? JSF 2.2 permet de profiter des services offerts par JSF (validation de données, affichage automatique des messages d’erreur, utilisation

simple d’Ajax, …) tout en utilisant un attribut ou un composant HTML5

         R. Grin                                                           JSF                                                        page 154

2 possibilités

? On peut utiliser un attribut HTML5 (attribut « passthrough ») dans un composant JSF

? Exemple : attribut placeholder de <input> alors qu’il n’est pas un attribut de <h:inputText>

? L’attribut sera passé tel quel à la balise HTML générée à la fin du cycle de vie JSF

? On peut aussi utiliser une balise HTML5, tout en profitant des facilités de JSF avec des attributs traités par JSF

         R. Grin                                                           JSF                                                        page 155

? un composant JSF

R. Grin

Attributs HTML5 en JSF

Etudions d’abord le cas d’un attribut HTML5 dans

JSF

page 156

Balise HTML5 en JSF

? Etudions maintenant comment insérer une balise HTML5 dans une page JSF, tout en profitant des avantages de JSF (expressions EL comme valeurs, conversions, validations, messages d’erreur,…)

R. Grin                                                           JSF                                                        page 158

Composant HTML5 traité par JSF

? Le composant HTML5 est transformé en un composant JSF suivant un mapping qui tient compte du nom de la balise et éventuellement de certains attributs de la balise

? Exemple : <input type="file"> est transformé en <h:inputFile>

   R. Grin                                                           JSF                                                        page 161

Composant HTML5 sans équivalent JSF

? Si le composant HTML5 n’a pas de correspondance dans JSF, JSF crée un composant spécial de balise

<jsf:element>

? On peut ajouter des capacités Ajax à un tel composant (voir exemple à suivre), mais seulement quelques attributs JSF liés aux événements JavaScript

? Les valeurs des attributs HTML5 peuvent contenir des expressions EL comme pour les composants JSF

   R. Grin                                                           JSF                                                        page 162

Ressources

R. Grin                                                           JSF                                                        page 165

Ressources des pages Web

? Les pages HTML font le plus souvent appel à des ressources externes : images, fichier CSS, code Javascript,…

? Il faut utiliser des balises JSF dédiées aux ressources à la place des balises HTML ; en ce cas JSF va chercher les ressources dans le répertoire resources placé sous la racine des pages Web

R. Grin                                                           JSF                                                        page 166

CSS

? Le plus souvent on met les fichiers CSS dans un sous-répertoire css du répertoire resources

<h:outputStylesheet name=""/>

R. Grin                                                           JSF                                                        page 167

JavaScript

? Le plus souvent on met les fichiers JavaScript dans un sous-répertoire js du répertoire resources

<h:outputScript name="" />

? Par défaut, le script sera placé dans la page HTML à l’endroit  où on a mis la balise ; on peut ajouter un attribut target pour indiquer où le mettre (par exemple target="head")

R. Grin                                                           JSF                                                        page 168

Image

<h:graphicImage name="" />

R. Grin                                                           JSF                                                        page 169

Thèmes

? Depuis JSF 2.2 on peut avoir des thèmes qui réunissent les ressources en utilisant l’attribut library des balises que l’on vient de voir

? En ce cas, chaque librairie correspondra alors à un thème différent, par exemple on aura un thème « defaut » et un thème « dark »

? Sous chacun des répertoires defaut et dark (placés sous le répertoire resources), on retrouvera les répertoire css, js et image qu’on vient de voir

? Il suffit alors de changer de librairie pour changer à la fois le CSS, le JavaScript et les images

R. Grin                                                           JSF                                                        page 170

Flots (faces flow)

R. Grin                                                           JSF                                                        page 171

Présentation

? A la manière des « wizards », les flots de pages (en fait, flots de nœuds, comme on le verra plus loin) sont des ensembles de pages qui partagent des informations communes (entreposées dans un backing bean de portée Flow)

R. Grin                                                           JSF                                                        page 172

Exemple

? Les pages qui permettent à un utilisateur de créer un compte avec ses informations personnelles, l’adresse de livraison, l’adresse de facturation et les informations sur sa carte de crédit

? Chaque type d’information est donnée sur une page différente

? Souvent la dernière page demande confirmation de toutes les données saisies et on peut lancer leur enregistrement ou un traitement avec les informations recueillies sur toutes les pages

R. Grin                                                           JSF                                                        page 173

Navigation avec un flot

? On ne peut entrer dans le flot que par la page de démarrage ; les autres pages du flot ne sont pas atteignables de l’extérieur du flot

? Quand on est dans le flot, on ne peut aller que vers des pages du flot ou vers la page de sortie

? Pour sortir du flot il suffit de naviguer depuis une page du flot vers la page de sortie

? Dès que la navigation amène à la page de sortie, les backing beans de portée flow sont supprimés automatiquement par CDI

R. Grin                                                           JSF                                                        page 174

Navigation par requête POST

? Malheureusement la navigation ne marche pas toujours bien si on utilise des requêtes GET ou des requêtes POST avec redirection (on oublie le modèle PRG dans les flots)

? Il est donc conseillé de n’utiliser que des requêtes POST ; dans les cas simples on peut tester avec des requêtes GET mais souvent on se retrouve avec des messages d’erreurs pour des adresses non trouvées ou bien avec une impossibilité de sortie du flot

         R. Grin                 JSF                                         page 175

Plusieurs flots

? Les flots peuvent être enchaînés séquentiellement ou bien emboités les uns dans les autres

         R. Grin                                                           JSF

page 176

Portée

? Comme la portée conversation le portée flot (annotation des backing beans par @FlowScoped) est entre la portée requête et la portée session

? La portée flot est une portée CDI

? Au contraire de la portée session, la portée flot n’a pas de problème si l’utilisateur ouvre plusieurs onglets du navigateur sur la même application

         R. Grin                 JSF                                         page 177

Utilité

? L’utilisation d’un enchaînement de pages pour obtenir de l’utilisateur un ensemble d’informations est fréquent

? Avant JSF 2.2, un backing bean de portée conversation était le plus souvent utilisé, avec les difficultés occasionnées par cette portée

? Un flot de pages

? simplifie la programmation d’une telle situation

? facilite la modularité

? peut être réutilisé dans des applications différentes

         R. Grin                                                           JSF                                                        page 178

Similaire à une méthode Java

? Un seul point d’entrée, plusieurs points de sortie possibles

? Paramètres d’entrée et valeur de retour

? Peut être appelé d’un autre point de l’application

? Interface bien définie mais les détails de l’implémentation sont cachés

? Un flot peut en appeler un autre et les portées s’empilent et se dépilent comme dans une pile d’exécution de méthodes

         R. Grin                 JSF                                         page 179

Définition d’un flot

? Suit le principe « Convention plutôt que configuration » : on peut définir un flot en créant un répertoire dans la racine des pages JSF de l’application

? Si on n’utilise pas la « convention », le flot peut être configuré dans le fichier <nom-flot> placé dans le répertoire qui contient les pages du flot, dans le fichier ou bien par programmation avec un producteur de Flow CDI

         R. Grin                                                           JSF                                                        page 180

Définition d’un flot par convention

? Répertoire dans la racine des pages, du même nom que le flot

? Dans le répertoire,

? Une page du même nom que le répertoire (et suffixe

.xhtml) comme nœud de démarrage du flot

? Les pages qui sont dans le flot

? Un fichier de configuration obligatoire nommé

<nom-flot>-flow.xhtml (vide si on n’a rien à configurer)

? En dehors du répertoire la page de sortie de nom

<nom-flot>-return.xhtml

         R. Grin                 JSF                                         page 181

Code pour entrer et sortir

? Les exemples suivants supposent que la convention a été suivie (pas de configuration)

? Exemple de code pour entrer dans le flot nommé flot1 (page flot1.xhtml mise dans le répertoire flot1) :

<h:commandButton id="start1" value="Entrer dans Flot1" action="flot1"/>

? Exemple de code pour sortir du flot nommé :

<h:commandButton id="home" value="home" action="/flot1-return" />

Fichier flot1-return.xhtml situé en dehors du répertoire flot1

         R. Grin                                                           JSF                                                        page 182

Configuration avec fichier XML (1/2)

? Si la convention ne convient pas, on peut définir la configuration dans un fichier de configuration non vide (fichier placé dans le répertoire du flot ou fichier global )

? Il doit alors contenir au moins la définition de l’id du flot et une déclaration de page de sortie du flot (il peut y avoir plusieurs balises <flow-return> pour plusieurs pages de sorties) :

<flow-return id="first-return-id">

<from-outcome>/retour</from-outcome>

</flow-return>

R. Grin                                                           JSF                                                        page 184

Configuration avec fichier XML (2/2)

? Le fichier peut aussi configurer

? le nœud de démarrage

? d’autres nœuds du flot

? des paramètres à passer au flot (<inbound-parameter>)

? un initialiseur, méthode exécutée avant l’entrée dans le flot ; pourra avoir accès aux paramètres dans la version JSF 2.3, buggé dans les versions précédentes

? un « finalizer », méthode appelée juste avant la sortie du flot

R. Grin                                                           JSF                                                        page 185

Exemple de fichier XML minimal

<faces-config version="2.2"   xmlns="; xmlns:xsi="; xsi:schemaLocation="

">

<flow-definition id="flot1"> <flow-return id="return1">

<from-outcome>#{()}</from-outcome>

</flow-return>

                                                                                                                             </flow-definition>                              En valeur retour, l’id de la vue

                                                                                                                         </faces-config>                                 ou bien, si la vue n’est pas définie,

le chemin par rapport à la racine ; par exemple /index (sans le suffixe)

                                                                                                                       R. Grin                                                           JSF                                                        page 186

Types de nœuds

? Les types de nœud sont décrits dans la javadoc de la classe .FlowHandler) :

? View, page JSF « normale »

? Switch, liste d’expressions EL de type boolean ; la 1ère expression qui est évaluée à true détermine le prochain nœud

? Return, arrête le flot en cours et définit la page affichée à la sortie du flot (page qui n’est pas dans le flot)

? Method Call, appel d’une méthode (avec paramètres) dont la valeur de retour détermine le prochain nœud

? Faces Flow Call, appel d’un autre flot ; au retour de cet autre flot, le flot reprend la main (pile de flots)

  R. Grin                                                           JSF                                             page 187

En savoir plus sur les flots…

? Les informations détaillées sur ces nœuds et les autres façons de définir et de configurer un flot ne seront pas étudiées dans cette section d’introduction aux flots

? Références pour plus de détails :

? Tutoriel Java EE 7, partie III : #CHDGFCJF

? (extrait livre MASTERING

JAVASERVER FACES 2.2 de Anghel Leonard).

  R. Grin                                                           JSF                                                        page 188

Decouvrir ces documents

  • Cours pour apprendre la programmation Assembleur Perfectionnement

    Cours pour apprendre la programmation Assembleur Perfectionnement

  • Cours sur les bases de donné perfectionnement

    Cours sur les bases de donné perfectionnement

  • Tutorial sur l’intégration d'AJAX avec le Framework DWR

    Tutorial sur l’intégration d'AJAX avec le Framework DWR

  • Formation complet de .NET Framework

    Formation complet de .NET Framework

  • Cours Déployer une application cliente avec le Framework .NET

    Cours Déployer une application cliente avec le Framework .NET

  • Programmation web langage perfectionnement

    Programmation web langage perfectionnement

  • Apprendre le développement d'applications web avec le Framework GWT (Google Web Toolkit)

    Apprendre le développement d'applications web avec le Framework GWT (Google Web Toolkit)

  • Démarrer avec le Framework JAVA MapReduce Hadoop et Spark

    Démarrer avec le Framework JAVA MapReduce Hadoop et Spark

Articles connexes

  • Cours de soutien scolaire bénévole - Informations et conseils
  • Cours particuliers : une nouvelle école informelle ?
  • 16 meilleurs IDE / EDI pour en Django Python (Comparatif)
  • Tuto Python & Django : créer une page web
  • Quel logiciel de gestion du planning de cours choisir ?
  • Placement d'Or : Règles et astuces pour réussir son investissement
  • Comment créer et convertir vos vidéos pour vos cours en ligne ?
  • Exercice Access 2003 : gestion des cours avec requêtes
  • Contactez-nous
  • A propos de nous
  • On recrute
  • Rechercher dans le site
  • Politique de confidentialité
  • Droit d'auteur/Copyright
  • Conditions générales d'utilisation
  • Plan du site
  • Accueil
  • Blog
  • Finance et compta.
  • Formations Pro.
  • Logiciels & Apps
  • Organisation
  • Cours informatique
  • Aide à la rédaction
  • Etudes et Metiers
  • Science et Tech
  • Titans de la Tech
id 11354 02