rapport de projet d'application pour l'internettraores/jee_rapport.pdf · fragment...
Post on 03-Jun-2020
10 Views
Preview:
TRANSCRIPT
ENSEEIHT
Rapport de Projet d'Application pour l'Internet
Site de location de matériel et d'édition de devis
Bastien BARTHET, Adrien CHAMPION, Benoit ESTEVENON, Thibaut ETIENNE, Bastien LEHMANN
Juin 2009
2
1 Sommaire 2 Introduction ..................................................................................................................................... 3
3 Cahier des charges du client ............................................................................................................ 3
4 Technologies employées ................................................................................................................. 3
5 Côté serveur .................................................................................................................................... 4
5.1 Modèle entité de la base de données ..................................................................................... 4
5.2 Beans ....................................................................................................................................... 5
6 Sécurité et authentification ............................................................................................................. 5
7 Côté client........................................................................................................................................ 5
7.1 L’architecture du site ............................................................................................................... 5
7.2 AJAX ......................................................................................................................................... 6
7.2.1 Ajax.Request .................................................................................................................... 6
7.2.2 Ajax.Updater .................................................................................................................... 7
7.2.3 D’autres façons de gérer les requêtes ............................................................................. 7
7.2.4 Les effets graphiques ....................................................................................................... 7
7.3 Servlet et JSP ........................................................................................................................... 8
7.3.1 Création d’un client ......................................................................................................... 8
7.3.2 Identification d’un client ................................................................................................. 8
7.3.3 Edition d’un profil client .................................................................................................. 9
8 Génération de devis et facture en PDF ......................................................................................... 10
8.1 Pourquoi ? ............................................................................................................................. 10
8.2 Intégration générale à l’architecture du site ......................................................................... 10
8.3 Outils utilisés pour la génération .......................................................................................... 10
9 Répartition du travail..................................................................................................................... 10
10 Problèmes rencontrés ............................................................................................................... 11
10.1 Castage d'ArrayList ................................................................................................................ 11
10.2 Internet Explorer vs Firefox ................................................................................................... 11
10.3 Adressage relatif des fichiers PDF généré ............................................................................. 11
11 Conclusion ................................................................................................................................. 12
3
2 Introduction Après avoir étudié plusieurs technologies web en cours, le présent projet a pour objectif de les
mettre en application sous la forme d’un site web. Le thème de ce dernier n’est pas imposé, mais il
doit être du type e-commerce. C'est-à-dire qu’il doit proposer la vente ou location de différents
objets.
3 Cahier des charges du client Ici, il s’agira d’un site de location en ligne de matériel d’une association de technique de spectacle
(Son&Lumière).
Il s’agit d’un élément primordial. En effet, c’est lui qui va aiguiller le développement du site. Il vise à
définir exhaustivement les spécifications de base du site à réaliser.
La demande est de pouvoir parcourir le parc de matériel, d'en faire un panier à la manière d'un
quelconque site de e-commerce, et enfin de pouvoir éditer les devis, facture et bon de livraison.
Le stockage de toutes les commandes passées doit être également assuré.
Deux types d'utilisateurs sont prévus quant à l'utilisation du site :
les clients. Ils peuvent consulter les produits, constituer un panier, voir leurs commandes
passées ou en cours, et éditer leur devis et ainsi que leur profil.
l'administrateur. Il peut modifier la base de données des produits, modifier n'importe quelle
commande, et visualiser les clients. Il est le seul à pouvoir éditer une facture ou un bon de
livraison.
4 Technologies employées Le but des technologies employées est de bien séparer le modèle, la vue et le contrôleur (MVC). Ainsi
il est aisé de travailler sur chaque parti indépendamment. De plus, la modularité ainsi apportée
permet de répartir facilement les différentes tâches entre les différents membres du groupe.
Le côté serveur, ou Back End, est écrit en EJB3 simplifiant ainsi la gestion des entités de la base de
4
données et la communication avec les clients. Des Servlets de manipulation des EJB sont déployés
côté client pour chaque action potentiellement effectuée par le client. L'interface utilisateur se
présente sous forme de pages HTML intégrant du JavaScript, de l'AJAX, du CSS et interaction avec les
Servlets via des JSP.
5 Côté serveur
5.1 Modèle entité de la base de données
Voici le schéma Entité-relation de la base de données déployée. Chaque client possède des
commandes. Chaque commande possède des produits sous la forme de couple (produit, quantité),
regroupé dans le type ProduitQuantité, pointant sur la base de données des produits.
Une fois une commande validée, l'objet Commande est supprimé et est remplacé par un objet
CommandeValidee, de façon à ne plus évoluer avec la BD. En effet si l'administrateur modifie le prix
d'un produit dans la BD, toutes les commandes en cours utilisant ce produit se verront modifiées
(aucun prix total n'est stocké, mais uniquement les prix unitaires et les quantités).
Afin de mieux distinguer les produits d'une catégorie ou d'une sous-catégorie, et de pouvoir lister
une commande par catégorie, des structures plus complexes de stockage furent envisagées, comme
définir des types génériques ou des HashMap. Le choix d’une liste ordonnée c’est finalement imposé
pour représenter les produits d'une commande. La fonction d'ajout regroupe le nouveau produit
N
1
1 N 1
1 N 1 1
Adresse
int id
String ville
String rue
int codePostale
Client
String login
String role
int reduction
String password
String beneficiaire
String email
String tel
Adresse adr
Collection<Commande>
Collection<CommandeValidee>
CommandeValidee
int id
String nom
String cheminVersImage
String cheminVersFacture
String cheminVersBonDeLivraison
Produit
Int id
String name
String description
int quantite
Float prix
String cheminVersImage
String categorie
ProduitQuantite
Int id
Produit p
int quantite
Commande
int id
String titreCommande
Date dateSortieMateriel
Date dateRetourMateriel
Collection<ProduitQuantite>
5
avec ceux de sa catégorie/sous-catégorie, afin de pouvoir ensuite lister les produits de façon plus
claire sur les devis.
5.2 Beans Pour manipuler ces entités, 3 classes de type SessionBeans ont été déployées pour gérer
respectivement les Produits, les Commandes et les Clients. Chacun fourni au client les fonctions
nécessaires à l'utilisation, en restreignant ainsi les risques de mauvaise utilisation.
6 Sécurité et authentification Le problème de l'authentification des clients et de l'identification du rôle de celui-ci (administrateur
ou simple client) a été géré par l'ajout de la clé client à la session. La session, de type HttpSession,
permet de faire persister des informations tout au long d'une connexion, jusqu'à un time-out ou un
retrait des informations. Tout ceci est géré par les servlets. Le client rentre donc son login et mot de
passe, qui sont ensuite contrôlé coté Beans, puis en cas de bonne identification le serveur renvoi au
client son rôle, qui est inscrit dans la session avec la clé client. Ce contrôle se passe donc côté Servlet
et permet ainsi à chaque action du client de savoir, d'une part si il est bien authentifié et autorisé à
appeler la méthode qu'il appelle, et d'autre part à connaître l'identité du client à chaque instant.
7 Côté client
7.1 L’architecture du site Notre site ne dispose vraiment que de trois pages:
la page d'accueil
la page client (une fois ceux-ci loggés)
la page administrateur (une fois celui-ci loggé)
A l'intérieur de ces pages, toutes les actualisations se font par mise à jour par fragment à l'aide
d'AJAX et en particulier de la librairie prototype.js (http://www.prototypejs.org/).
Deux objets sont principalement utilisés, Ajax.Request et Ajax.Updater.
6
7.2 AJAX
7.2.1 Ajax.Request
Voici un exemple d'utilisation d'Ajax.Request :
7
function adminGetClients() {
var date = new Date();
var param = "dummy=" + date;
new Ajax.Request('ActionListerClient', {
method : 'post',
parameters : param,
onComplete : function(response) {
$('mainDisplay').innerHTML = response.responseText;
}
});
}
Ajax.Request est adapté aux appels à une servlet. Une fois la requête terminée, l'action définie dans
le champ onComplete est exécutée, ici on actualise le fragment central avec la liste des clients
(renvoyée sous forme d'une JSP par la servlet appelée).
7.2.2 Ajax.Updater
Voici un exemple d'utilisation d'Ajax.updater:
function ajaxUpdater(container, url) {
new Ajax.Updater(container, url);
}
Nous utilisons exclusivement Ajax.Updater pour des appels directs aux JSPs sans passer par une
servlet. La fonction considérée ici permet de mettre à jour un fragment (typiquement un div) dont
l'id est « container » avec la JSP à l'adresse « url ».
7.2.3 D’autres façons de gérer les requêtes
Prototype.js est compatible avec le standard JSON (http://www.prototypejs.org/learn/json) qui, pour
ce que nous en avons lu, semble présenter des avantages certains et est fortement recommandé par
les « gros bonnets » du domaine. Cependant, à cause du nombre conséquent de projets en simultané
et de l'approche des partiels nous avons préféré nous en tenir à des technologies plus facilement
abordables.
A noter également que prototype.js gère également les formats couramment employés pour la
création de pages ou de fragments dynamiques tels que XML et DOM.
7.2.4 Les effets graphiques
Pour étoffer l'aspect visuel du site, nous avons tout d'abord commencé à nous pencher sur plusieurs
librairies isolées telles que Rico (http://openrico.org/), ainsi que sur des scripts spécialisés (comme
on peut en trouver ici : http://www.miniajax.com/).
Rapidement sont apparus de gros problèmes de compatibilité entre les librairies et les scripts par
rapport aux noms de variables, aux noms de fonctions, ainsi qu'au CSS pour les scripts spécialisés. De
plus, les librairies telles que Rico fournissent des effets de trop haut niveau assez peu modifiables à
moins de modifier le code source, chose que nous n'avions pas le temps de faire.
Il a donc été décidé d'utiliser scriptaculous (http://script.aculo.us/) qui donne accès à des effets assez
simples mais plutôt efficaces et surtout plus facilement adaptables au cas par cas.
8
Les effets principalement utilisés sont Effect.BlindUp, Effect.BlindDown, Effect.Appear, Effect.Fold...
(http://wiki.github.com/madrobby/scriptaculous).
En particulier, il a été défini une petite fonction très pratique:
// Fonction d'apparition et de disparition
function slideThat (that) {
var dis = document.getElementById(that);
var state = dis.getAttribute("class");
if (state == "on") {
Effect.BlindUp(that);
dis.setAttribute("class", "off");
} else {
Effect.BlindDown(that);
dis.setAttribute("class", "on");
}
}
Elle permet de faire apparaître ou disparaître un fragment (un div) très facilement. Cependant elle
n'est pas très propre et pose un problème : dans la mesure où la classe du fragment est utilisée pour
savoir s'il est visible ou non, deux clics trop rapprochés rendront incohérent l'état de classe si le
fragment n'a pas eu le temps de terminer l'effet (apparition ou disparition) entre les deux clics.
7.3 Servlet et JSP Le but est ici de créer des servlets permettant de manipuler les clients, les produits et les
commandes. La première phase étant la création d'un nouveau client, qu'il puisse s'authentifier et
modifier son profil.
7.3.1 Création d’un client
De manière classique, tous les paramètres nécessaires à la création d'un client sont récupérés :
String login = request.getParameter("login");
String password = request.getParameter("password");
String rue = request.getParameter("rue");
Grâce au générateur de contexte, un clientSessionBean est créé auquel se rajoute le nouveau client
ainsi crée :
ClientSessionBeanRemote sessionBean =
GenerateurContext.getClientSessionBeanRemote();
Client c = new Client(login, role, reduc, password, beneficiaire, email,
tel, adr, listeDesCommande);
sessionBean.creer(c);
La redirection se fait alors vers une JSP personnalisée souhaitant la bienvenue à l'utilisateur identifié
avec succès. Sinon, il est invite à s’identifier de nouveau via des alertes AJAX.
7.3.2 Identification d’un client
Comme précédemment, tous les paramètres nécessaires à l'identification d'un client sont récupérés
et un clientSessionBean est créé/récupéré grâce au générateur de contexte.
9
String login = request.getParameter("login");
String password = request.getParameter("password");
Sur ce session bean, la méthode identifierClient renvoie le rôle du client, admin ou client. Pour la
suite des opérations, en plus d’insérer le login à la session, le rôle y est également ajouté, ce qui
déterminera les actions possible à une personne connectée. Un client ne pourra pas effectuer les
mêmes actions qu'un administrateur.
ClientSessionBeanRemote sessionBean =
GenerateurContext.getClientSessionBeanRemote();
String role = sessionBean.identifier(login, password);
HttpSession session = request.getSession(true);
request.setAttribute("login", login);
Ensuite, une redirection s'effectue en fonction du rôle de la personne connectée.
if (role.equals("admin")) {
request.getRequestDispatcher("jsp/logAdmin.jsp").forward(request,resp
onse);
} else {
request.getRequestDispatcher("jsp/logClient.jsp").forward(request,res
ponse);
}
7.3.3 Edition d’un profil client
Encore une fois, les bons paramètres nécessaires à l'édition d'un client sont récupérés. La page web
affectant les valeurs à ces paramètres se charge de passer la valeur de paramètre déjà existante si
l'utilisateur ne souhaite pas la modifier.
Ensuite, toutes les fonctions disponibles sont appelées dans le haricot pour effectuer les
changements. Petit plus, si le nouveau mot de passe n'est pas vide, l'ancien est conservé.
Il est également possible pour un administrateur d'éditer tous les clients, de la même manière que
précédemment, à ceci prés qu'il peut changer sa réduction, mais pas les paramètres
d’authentification, login et mot de passe.
Pour les produits et les commandes le fonctionnement est assez similaire, en effet les fonctions de
création, d'édition, et de suppression fonctionnent de la même manière. A la différence près que
selon le rôle de la personne connectée certaines actions ne seront pas disponibles. En effet l'ajout
d'un produit dans la base de données ainsi que son édition et sa suppression ne seront accessibles
qu'à un administrateur.
Mis à part le fait que graphiquement ces actions ne seront disponibles que pour un administrateur
connecté, un test sur le rôle est effectué pour éviter toute fraude de la part d'un client malveillant.
HttpSession session = request.getSession();
String role = (String)session.getAttribute("role");
if (role.equals("admin")){
try {
ProduitSessionBeanRemote sessionBean =
GenerateurContext.getProduitSessionBeanRemote();
sessionBean.creerProduit(name, description, prix,
categorie, sousCategorie, quantite, cheminversImage);
10
} catch (Exception e) {
request.setAttribute("error",e);
request.getRequestDispatcher("error.jsp").forward(request,
response);
}
}
else {
//renvoyer a l'identification
}
8 Génération de devis et facture en PDF
8.1 Pourquoi ? Afin de conserver trace des prestations qu'a offert le Club Animation, il est nécessaire de conserver
un élément qui rende compte de la transaction à une certaine date, indépendamment des évolutions
des prix et du parc matériel. Pour cette raison, la génération de fichiers PDF est excellente car une
fois écrit, son contenu restera statique même s'il y a des modifications en Back End. Les fichiers
générés seront stockés sur serveur grâce à leur n° de commande et leur type (facture, devis ou bon
de livraison). En ayant le chemin d'accès inscrit en Base de données, il serait ainsi simple de les
retrouver pour les renvoyer au client par la suite. A noter que pour plus de portabilité il serait plus
judicieux de stocker uniquement le n° de facture et que le Front End reconstitue lui-même le chemin
d'accès selon sa propre méthode de stockage.
8.2 Intégration générale à l’architecture du site L'intégration se fait logiquement du côté où les fichiers sont écrits, c'est à dire en Front End. La
génération étant de plus "interactive" (i.e. lancée par l'utilisateur), les Servlets semblent toutes
indiquées pour ce genre de traitement. Le traitement de l'intégralité de la tâche n'est pas compliqué
en soit :
La commande et le client étant fournis (l’authentification est donc obligatoire), il suffit de les
disséquer pour en tirer les informations importantes et les écrire dans un fichier avec une
présentation particulière.
La clé du chemin d'accès au fichier doit ensuite être mémorisée dans la base de données
pour un appel ultérieur.
8.3 Outils utilisés pour la génération L'idée était au départ de générer un fichier source LaTeX pour le compiler à la volée et générer le
PDF. Cette solution a été abandonnée car les librairies LaTeX n'auraient pas forcément été
présentes/installables sur le serveur. De plus, ces librairies sont très lourdes puisqu'il y a plusieurs
centaines de Mo.
A la place, il a été choisi d'utiliser du Java pour générer les PDF. Grâce à la librairie iText (disponible
sur http://www.lowagie.com/iText/), il est possible de décrire un document PDF en y ajoutant des
éléments au fur et à mesure. Par contre, l'étape d'écriture d'un fichier source est sautée. Pour
comparaison avec le LaTeX, la commande du site serait notre fichier source et notre servlet serait le
compilateur LaTeX.
11
9 Répartition du travail Nous avons très vite défini notre projet et reparti les tâches selon les envies de chacun. Bastien L.
s'est chargé du Back End, épaulé pour la conception papier par Benoit. Benoit a donc aidé sur le Back
End, bien que son rôle principal ait été la génération de PDF, via la librairie iText, à partir d'une
servlet. Bastien B. a réalisé l'ensemble des servlets, gérant ainsi l'authentification, et les liens entre
Beans et JSP, selon les besoins des autres parties. Adrien a conçu les JSP, classe JavaScript et l'AJAX
du site, aidé par Thibaut. Thibaut s'est occupé du CSS, de l'HTML et du graphisme, en aidant ensuite
Bastien B. sur les servlets et Adrien sur les JSP.
Les parties étant clairement définies, le travail a très vite évolué individuellement, et collectivement
via un SVN global. Le SVN a vraiment permis d'avoir des tâches autonomes puisque pour les liens
avec les autres parties, il était possible d'aller voir ce qui avait été fait. Cependant certaines tâches
furent des bloquantes, nécessaires à l'avancement général, notamment le BackEnd dont les
interfaces et entités ont du très vite être défini.
10 Problèmes rencontrés
10.1 Castage d'ArrayList Lors d'un accès à une collection issue d'un lien OneToMany, le castage en ArrayList lève une
exception, expliquant qu'il est impossible de caster le PersistenteBag. Aucune solution n'a été trouvé,
d'où l'impossibilité de rattacher une commande à un client (accès possible via l'administrateur pour
l'instant, qui récupère la liste complète des commandes), ni de rattacher des produits à une
commande. Les modifications des paramètres de fetch, des types de liste (List, ArrayList, Collection)
n'ont rien donné.
Pour pouvoir cependant présenter une génération de PDF sans réel commande, le modèle entité-
relation a été rapidement recopié en Front End de façon à pouvoir tester le générateur sur une
commande non vide!
10.2 Internet Explorer vs Firefox Lors de la conception du CSS divers problèmes de compatibilité ont été rencontrés. En effet, IE et FF
n'interprètent pas exactement de la même manière le code. De fait, la position de certains boutons
est aléatoire, ce qui est très irritant. Suite à plusieurs tentatives de résolution, il s'est avéré que
c'était peut être l'insertion de code avec AJAX ainsi que les effets graphiques qui perturberaient la
lecture du CSS.
10.3 Adressage relatif des fichiers PDF générés Le problème majeur est posé par la portabilité : comment savoir où vont aller les fichiers, en
particulier si on change de machine serveur. On ne peut donc pas utiliser de chemin absolu pour
indiquer où stocker les fichiers. Heureusement les chemins relatifs sont utilisables lors de l'écriture
du fichier, en écrivant dans le répertoire courant, c'est le répertoire bin de JBOSS qui sera utilisé.
Sachant cela, il est possible de les stocker à l’endroit souhaité.
Vient ensuite la récupération du fichier par la servlet et là les choses sont plus difficiles : en chemin
relatifs ou absolus, il n'a pas été possible de récupérer les fichiers générés. Le problème a donc été
contourné en mettant le lien hypertexte vers le fichier directement dans la page du client.
12
11 Conclusion Ce projet fut très intéressant de part son intérêt. En effet, construire un site de e-commerce permet
d'utiliser les connaissances théoriques dans un but extrêmement précis et dont le résultat est
immédiatement visible. D'autre part, la répartition des tâches s'est avérée être un point clé du
déroulement du projet. De manière générale, la communication entre membres s'est très bien
déroulée, ceci grâce à une bonne entente, une bonne ambiance et au SVN.
Cependant, face à la simultanéité des projets et partiels et à la configuration chaotique des
différents outils de développement, il nous a été difficile de mener à bien ce projet comme nous
l'aurions souhaité. Bien que la majeure partie du site fonctionne, il reste quelques fonctionnalités à
implémenter qui mériteraient que l'on se penche dessus plus tard.
In fine, ce projet nous a beaucoup apporté tant sur le plan technique que relationnel. Et bien que
partiellement inachevé, nous sommes heureux de ce que nous avons pu réaliser en aussi peu de
temps.
top related