CAT | J2EE
Le but principal d’ICEfaces est de faciliter le développement d’une application sophistiquée avec une interface riche pour une application JSF. La construction de la page est basée sur l’insertion de tags, à l’image de blocs, avec la flexibilité de modifier bon nombre de paramètres pour chacun d’eux. La suite des composants disponibles utilise un pont Ajax commun et une technique direct to DOM unique à ICEfaces. Ceci permet de créer une application riche sans avoir à écrire une seule ligne de code JavaScript pour gérer les communications asynchrones.
L’approche D2D, unique à ce cadre applicatif, effectue une comparaison de l’ancien DOM et du nouveau durant la phase Render Response de JSF pour minimiser la transmission de données vers le client.
L’intégration des effets de script.aculo.us y est aussi centrale. La majorité des composants peuvent facilement être animés pour rendre l’expérience du client plus riche. Ces effets peuvent être générés autant au niveau du navigateur qu’à distance par le serveur.
La sécurité est aussi centrale à ce cadre applicatif. Il respecte les standards Java EE et permet une sécurité orientée rôles. L’intégration des composantes dans l’arbre JSF peut être dépendante des rôles de sécurité que possède l’utilisateur. Par exemple, un utilisateur possédant le rôle d’éditeur n’aura pas les mêmes composantes sur une même page qu’un utilisateur possédant seulement le rôle de lecteur.
Finalement le principe du drag & drop, un principe avancé en web tel qu’illustré dans la ICEfaces, est parfaitement intégré et facile d’utilisation pour le développeur. La modification de simples paramètres d’un composant permet de les rendre déplaçables pour l’intervention naturelle dont l’utilisateur est habitué dans une application classique.
Ajax Push
La nouvelle évolution du Ajax est l’Ajax push, nommé aussi Comet. Cette technique d’avant-garde permet de rétablir le lien manquant entre le serveur vers les clients. Cette technique permet donc à la couche applicative de garder un état pour chaque client, et de communiquer sur demande au client, sans aucune intervention nécessaire de la part, ou d’utilisation abusive de la bande passante. Cette possibilité est essentielle dans un outil de collaboration entre utilisateurs, car ils peuvent voir en temps réel les interventions des autres participants à l’opération commune.
La figure suivante présente les différentes techniques possibles pour tenir les informations à jour sur l’interface client. La première développée fut le polling. Cette technique consiste à effectuer une requête par intervalle de temps. Un événement survenant entre ce délai ne sera informé au client que lors de la prochaine requête de ce dernier. De plus, l’utilisation réseau pour cette technique est faramineuse. Par exemple, si un client est configuré pour faire une requête aux 10 secondes et un événement survient après 2 minutes, le client aura fait 12 requêtes inutiles avant d’obtenir cet événement. La première technique considérée comme Ajax Push est le long poll. Cette technique n’utilise qu’une seule requête par événement, peu importe le délai entre la requête initiale et ce dernier. Une nouvelle requête est initiée par la suite. Cette technique minimise l’utilisation réseau, mais nécessite quand même une communication par événement, ce qui peut augmenter sa demande en bande passante si ces événements sont trop nombreux. La plus récente technique Ajax Push est le streaming. Cette technique permet d’obtenir un nombre illimité d’événements par une seule requête initiale. Cette technique idéale n’est malheureusement pas disponible par tous les serveurs applicatifs J2EE. Glassfish avec son module Grizzly est l’implémentation actuellement qui supporte le mieux le streaming.
Implémentation Ajax Push d’ICEfaces
L’API de communication par Ajax push a trois avantages qui la différencient de ses compétiteurs. Premièrement, elle possède un outil de maintien et de surveillance des connexions. Cet outil configurable permet le maintien de connexions à long terme du serveur avec ces clients, en plus de détecter des connexions rompues abruptement. Il empêche ainsi d’avoir une série de connexions fantômes utilisant les ressources du système inutilement. Le second avantage est qu’ICEfaces permet le partage des connexions de plusieurs instances dans un même navigateur, palliant ainsi aux limitations du nombre de connexions d’un navigateur. Le dernier avantage est l’optimisation du rendu. En effet, il utilise le cycle JSF pour forcer la mise à jour de clients tout en prodiguant les outils de synchronisation à l’application.
Trois composantes majeures sont nécessaires à l’utilisation d’Ajax Push dans une application. Premièrement, le render manager est un JavaBean dans la portée applicative de l’application. Il s’intègre dans le cycle JSF et coordonne les requêtes. Il s’occupe aussi de l’enregistrement aux render groups. Le second composant est les render groups. Ces groupes permettent de rassembler les clients dans des ensembles dont le rendu se fera simultanément. Finalement, l’interface renderable est utilisée pour permettre à un objet d’être utilisé dans une requête d’Ajax Push. Leurs intégrations se fait comme illustré à la figure suivante.
Sources :
Hightower, Rick : JSF for nonbelievers: The JSF application lifecycle [ en ligne ]. Disponible sur : < http://www.ibm.com/developerworks/library/j-jsf2/> (consulté le 18 avril 2009)
IceSofts Technologies : Ajax Push [ en ligne ]. Disponible sur : < http://www.icefaces.org/main/ajax-java/ajaxpush.iface > (consulté le 18 avril 2009)
IceSofts Technologies : ICEfaces Component Suite [ en ligne ]. Disponible sur : < http://www.icefaces.org/main/ajax-java/jsf-components.iface > (consulté le 18 avril 2009)
Kiener, Micha et Goddard, Ted : Ajax Push For Revolutionary Enterprise Applications [ en ligne ]. Disponible sur : < http://jazoon.com/download/presentations/5420.pdf > (consulté le 18 avril 2009)
Cet article est un extrait du document Bureau virtuel par Ajax push, produit par Julien Chouinard
Introduction
JBoss AS simplifie grandement l’utilisation de la persistance en offrant qu’un seul choix de Persistance provider déjà configuré, Hibernate. C’est à la fois un atout et un défaut puisqu’Hibernate est un produit éprouvé et fiable, qui simplifie grandement le développement applicatif et s’intègre parfaitement dans Java persistance API (JPA). Ce document présentera donc les étapes de bases pour configurer une banque de connexions vers un serveur mySQL par JNDI. Ce document présente donc une technique d’utiliser les avantages de JBoss AS avec des entreprise JavaBean de troisième génération. Il ne ce veut cependant pas une référence complète de la création d’une application J2EE.
Configuration du Data Source
La configuration du data source ce fait séparé de l’application J2EE. Cela permet de facilement la modifier sans devoir recompiler l’application. Elle est référé dans cette dernière par son nom JNDI, peut importe son implémentation.
Il faut donc créer un fichier nommer du nom de l’application suivit d’un “-ds”. Ce fichier est de type XML. Pour des fins de démonstrations, nous utiliserons le nom d’application “project”. Donc le fichier “project-ds.xml” contiendra le texte suivant :
<?xml version=”1.0″ encoding=”UTF-8″?>
<datasources>
<local-tx-datasource>
<jndi-name>ProjectDS</jndi-name> (1)
<connection-url>jdbc:mysql://localhost:3306/project</connection-url> (2)
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>password</password>
<min-pool-size>5</min-pool-size> (3)
<max-pool-size>20</max-pool-size> (4)
<idle-timeout-minutes>0</idle-timeout-minutes>
<track-statements/>
</local-tx-datasource>
</datasources>
Le premier point important (1) est le nom JNDI qui sera utilité. Il est standard d’ajouter les lettres “DS” à la suite pour signifier la nature, data source, du composant. La configuration du chemin d’accès à la base de donnée ce fait au point (2). La base de donnée, ici “project” doit préalablement avoir été créé et que l’utilisateur est les droits appropriés de sur cette dernière. Si on désire utiliser les fonctionnalité de génération automatique de la base de donnée par JPA, il doit avoir les droits create et drop en plus de ceux régulier. La sécurité ce fera au niveau de l’application puisque l’application n’utilise qu’un seul utilisateur pour l’accès aux données. Finalement, les points (3) et (4) permette de gérer le nombre de connexions qui seront généré pour le système. La création d’une connexion vers la base de données est un processus lourd pour une application web c’est pour cela qu’il est recommander d’en générer plusieurs d’avances. Le nombre de connexions consommé par le système n’a pas une corrélation directe avec le nombre de clients dans le domaine. En effet, il est seulement le nombre limite de requêtes simultanés qu’il peut traiter. Cette technique utilise le principe selon lequel un client est inactif 90% du temps qu’il passe dans un système.
Configuration de la persistance
Le prochain fichier à configurer est le fichier de persistance dans le dossier meta-inf du EAR contenant les Entity Beans. Il est important de préciser ici que ces derniers ont été grandement allégé dans leur troisième génération par rapport aux précédente. Ils n’ont plus de réel différence avec des POJOs (Plan Old Java Object) réguliers. Il sont cependant administré par un entity manager qui gère automatiquement leur persistance et leur mise à jour, tout en laissant la possibilité de le faire manuellement.
Le but du fichier de persistance (persitance.xml) est donc de définir quel data source est utilisé par l’application et quel dialecte est utilisé pour communiquer avec la base de donnée.
<persistence>
<persistence-unit name=”project”> (2)
<jta-data-source>java:/ProjectDS</jta-data-source> (1)
<properties>
<property name=”hibernate.dialect” value=”org.hibernate.dialect.MySQL5Dialect”/>
<property name=”hibernate.hbm2ddl.auto” value=”create-drop”/>
<property name=”hibernate.show_sql” value=”true”/>
<property name=”hibernate.format_sql” value=”true”/>
</properties>
</persistence-unit>
</persistence>
Le point (1) réutilise ici le nom configuré dans l’étape précédente et fera une requête JNDI pour obtenir la data source associé à ce dernier. Le second point configure le persistence-unit name qui sera utilisé pour sélectionner l’entity manager associer à cette persistance.
Création d’un Entity Bean
L’application est maintenant prête à utiliser des entity beans. La troisième génération de ces derniers utiliser pleinement la configuration par annotation plutot que par xml. Elle permet de configurer le mapping entre les objets Java et leurs tables équivalentes.
@Entity (1)
@Table(name=”Student”)
public class StudentEntity {
@Id @Column(name=”user_name”, nullable=false) (2)
private String userName;
@Column(name=”first_name”, nullable=false) (3)
private String firstName;
[...]
@Column(name=”telephone”, nullable=false)
private String telephone;
@OneToMany(mappedBy=”student” ,fetch = FetchType.LAZY)
private List<ScheduleAssignationEntity> groupcourse;
@ManyToOne(fetch = FetchType.LAZY) (4)
@JoinColumn(name=”id_program”)
private ProgramEntity program;
@Version (5)
@Column(name=”version”, nullable=true)
private long version;
[getters et setters pour l'ensemble des attributs]
}
(1) : L’annotation entity definit l’objet comme un entity bean
(2) : La granularité des annotations est assez forte. On peut facilement définir des clefs et options pour chaque attributs.
(3) : l’annotation de column est optionnel mais permet de définir l’option de nullabilité.
(4) : Les entity beans permettent aussi d’effectuer directement le lien entre les objets Java et définir les options de fetch. Ici le patron de conception J2EE Lazy loading est utilisé.
(5) : L’annotation version permet d’implémenter le patron de conception Optimistic Lock
Utilisation de l’entity manager
L’utilisation de l’entity manager est très simple. Tout d’abord, on doit informer le système d’injecter ce dernier dans notre objet en ajoutant l’attribut suivant à notre Session Bean.
@PersistenceContext(unitName = “cheminot”)
private EntityManager em;
Par la suite, on peut utiliser cet attribut directement sans l’instancier. Par exemple pour rechercher un objet par sa clef on peut utiliser la ligne suivante :
GroupCourseEntity group = em.find(GroupCourseEntity.class, id);
Aussi simplement, on peut enregistrer un objet dans la base de donnée par la ligne suivante :
em.persist(schedule);
JPA permet quand même de faire des requêtes sur les objets comme s’ils seraient des tables.
List<GroupCourseEntity> groupes = (List<GroupCourseEntity>) em
.createQuery(
“SELECT g FROM GroupCourseEntity g WHERE g.course.acronym = :acronym AND g.quarter.current = true”)
.setParameter(“acronym”, sigle).getResultList();
Extensibilité de JPA
JPA ne peut être utilisé qu’au niveau des Sessions Beans pour une application conventionnelle. Cette approche favorise une bonne division des couches mais nécessite la création d’objets de transports entre chaqu’unes. Certains cadres applicatifs, tel que Seam, corrige cette situation et permette son utilisation à tout les niveaux.
