Création d’un formulaire de login Struts 2 avec stockage des données dans une base SQL
1 – L’architecture de notre application
Reprenons notre projet formulaire (vous pouvez télécharger le war ici )
A – Structure de notre projet et mise en place de l’environnement SQL.
1 – Intégrons le projet à éclipse galileo :
nous devons sélectionner le type de source à importer :
il nous faut maintenant configurer le Build Path et intégrer nos jar (bibliothèques java)
Faites un clic droit sur le nom du projet puis sélectionner propriétés.
puis ;
1 – Sélectionnez le Java Buil Path
2 – Sélectionnez l’onglet Librairies
3 – Cliquez sur Add Jars
4 – naviguez dans votre projet jusqu’au répertoire LIB, situé dans /webcontent/WEB-INF/ et sélectionnez tous les *.jar
5 – validez par ok.
l’ensemble des jars sont maintenant associés à votre projet qui ressemble à ceci :
Comme vu au tutoriel formulaires avec struts2 nous avons stocké nos mot de passe et nom d’utilisateur dans la classe Bdd.TableUtilisateur. Nous allons effacer cette classe qui ne va plus nous servir et monter notre serveur sql.
2 – mise en place du serveur SQl et création de la base.
Installons easyPhp (équivalents : wamp, mamp, xamp) que vous pouvez télécharger ici.
Pour lancer le serveur cliquez sur l’exécutable d’easyPHP (pour plus d’information sur la mise en place veuillez consulter ce tutoriel.
Nous allons créer notre première base nommée login. Ouvrez la console d’administration phpMyadmin en tapant cette adresse : http://127.0.0.1/home/mysql/
Nous allons maintenant créer notre table
puis nos champs :
voici le script Sql :
-- -- Structure de la table `identification` -- CREATE TABLE IF NOT EXISTS `identification` ( `id` int(11) NOT NULL AUTO_INCREMENT, `identifiant` text NOT NULL, `mdp` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; -- -- Contenu de la table `identification` -- INSERT INTO `identification` (`id`, `identifiant`, `mdp`) VALUES (1, 'admin', 'admin'), (2, 'user', 'user'); |
nous avons ajouter dans notre bases deux enregistrements.
3 – Configuration de la couche DAO (data object access).
Dans notre package model nous allons créer une interface de type DAO qui implémentera notre modèle DAO. Nous affecterons également une classe de type model à notre Utilisateur.java.
a- L’interface DAO.java
package model; import java.sql.Connection; import javax.naming.NamingException; /** * @author Olivier Guillou * fevrier 2009 */ public interface Dao { /** * Ouvre une connexion vers le SGBD. * @return Connection */ public Connection getConnection() throws NamingException; } |
Cette interface (contrat) obligera les classes dépendantes à implémenter la méthode getConnection();
b - Le modele Data Object Access ModeleDao.java
package model; import java.sql.Connection; import java.sql.SQLException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletContext; import javax.sql.DataSource; import org.apache.struts2.ServletActionContext; /** * @author Olivier Guillou * 2009 février * * Classe de connexion ModelDao. */ public class ModelDao implements Dao { //------------------------------------------------------------- // Properties //------------------------------------------------------------- /** * initialisation du context */ Context ctx = null; /** * Le DataSource */ DataSource dataSource=null; /** * La Connection */ //------------------------------------------------------------- // Others methods //------------------------------------------------------------- /* (non-Javadoc) * @see model.Dao#getConnection() */ public Connection getConnection() throws NamingException { ServletContext servletContext=ServletActionContext.getServletContext(); if(this.dataSource==null) { dataSource=(DataSource)servletContext.getAttribute("dataSource"); } Connection connection=null; if(dataSource!=null) { try { connection=dataSource.getConnection(); } catch(SQLException e) { System.out.println(e); } } return connection; } /** * @param dataSource */ public void setConnection(DataSource dataSource) { this.dataSource=dataSource; } } |
Cette classe implémente notre interface DAO et défini la méthode de connexion. Cette méthode de connexion utilisera un pool de connexion (une DataSource) qui est une simple fabrique de connexions vers la source de données SQL, dont le nom est stocké dans le web.xml et les paramètres de connexion dans le fichier context.xml
c - Le model utilisateur (dans notre cas) UtilisateurModel.java
package model; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import services.GestionConnexion; import bean.Utilisateur; /** * @author Olivier Guillou * 2009 février * * Model Utilisateur (requetes et mapping). */ public class UtilisateurModel extends ModelDao { //------------------------------------------------------------- // Attributs //------------------------------------------------------------- /** * initilisation de la connection */ Connection connexion = null; /** * initialisation du resultSet */ ResultSet resultat = null; /** * initialisation du PreparedStatement */ PreparedStatement requete=null; /** * initialisation du bean utilisateur */ Utilisateur utilisateur=null; //------------------------------------------------------------- // Methodes du model //------------------------------------------------------------- /** * Méthode de mapping Objet/relationnel pour l'Utilisateur * @param resultat * @return Utilisateur */ public Utilisateur mappingUtilisateur(ResultSet resultat) { // on instancie un nouvel utilisateur Utilisateur utilisateur = new Utilisateur(); try { // --------------- if ((resultat.getString("id") == null)) { utilisateur.setId(0); } else { utilisateur.setId(resultat.getInt("id")); } // --------------- if (resultat.getString("identifiant") == null) { utilisateur.setIdentifiant(""); } else { utilisateur.setIdentifiant(resultat.getString("identifiant")); } // --------------- if (resultat.getString("mdp") == null) { utilisateur.setMdp(""); } else { utilisateur.setMdp(resultat.getString("mdp")); } } catch (Exception e) { utilisateur=null; System.out.println("erreur de mapping :" + e); } return utilisateur; } /** * Methode d'accès aux données de l'utilisateur * @param loginForm * @param passwordForm * @return */ public Utilisateur Identifier(String loginForm, String passwordForm) { // initialisation de la requete String requeteString=null; Utilisateur utilisateur=null; try { // ouverture connexion connexion=super.getConnection(); // creation requète requeteString = "SELECT * FROM identification WHERE identifiant=? AND mdp=?"; // preparation requête requete=connexion.prepareStatement(requeteString); requete.setString(1,loginForm); requete.setString(2,passwordForm); // éxécution requête resultat= requete.executeQuery(); // On stocke le resultat dans l'objet utilisateur if(resultat!=null) { if(resultat.next()) { // mapping des attributs <=> champs Sql utilisateur=mappingUtilisateur(resultat); } } } catch(Exception e) { utilisateur=null; } finally { try { // Fermeture de la connexion if(resultat!=null) { GestionConnexion.closeResulset(resultat); } if(requete!=null) { GestionConnexion.closeRequest(requete); } if(connexion!=null) { GestionConnexion.closeConnection(connexion); } } catch(Exception errorConnection) { System.out.println("La fermeture de la connexion a provoqué une erreur " + errorConnection); } } return utilisateur; } } |
C’est le model associé au bean Utilisateur.java et que nous appellerons via la classe d’action UtilisateurAction.java. Le model va nous fournir un ensemble de méthode pour créer, supprimer, modifier nos informations en base de donnée. Nous remarquerons également une méthode de mapping qui réalise la transformation objet-relationnel c’est-a-dire : qui associe les attributs de ma classe Utilisateur.java aux champs de la table correspondante dans la base de donnée.
d - Le service de connexion au SGBD.
Nous allons maintenant configurer notre écouteur (DatasourceListener.java) , chargé de récupéré la dataSource.
package services; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.sql.DataSource; public class DatasourceListener implements ServletContextListener{ Context context=null; //fonction appelée lors de la création du lanceur public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext servletContext=servletContextEvent.getServletContext(); System.out.println("récupération du ServletContext" + servletContext); String dataSourceJNDI=servletContext.getInitParameter("dataSource"); System.out.println("récupération de la dataSourceJNDI" + dataSourceJNDI); try { context=new InitialContext(); DataSource dataSource=(DataSource)context.lookup(dataSourceJNDI); if(dataSource==null) { System.out.println("Echec lors de la récupèration de la datasource"); } else { System.out.println("DataSource chargée"); } servletContext.setAttribute("dataSource", dataSource); } catch(NamingException e) { throw new RuntimeException(); } finally { try { //fermer le context if(context!=null) { context.close(); } } catch(Exception e) { System.out.println("Erreur lors de initCtx !"); } } } //fonction appelée lors de la destruction du lanceur public void contextDestroyed(ServletContextEvent servletContextEvent) { try { //fermer le context if(context!=null) { context.close(); } } catch(Exception e) { System.out.println("Erreur lors de initCtx !"); } } } |
Il doit ête déclaré dans le fichier web.xml

e - Factorisation des fermetures de connexion : GestionConnexion.java
package services; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class GestionConnexion { // ferme le ResultSet public static void closeResulset(ResultSet resultat) { if(resultat!=null) { try { System.out.println("Resultset fermé avec succès"); resultat.close(); } catch(Exception e) { System.out.println("Erreur de fermeture du Resultset"); } } } // Ferme une requête public static void closeRequest(Statement requete) { if(requete!=null) { try { System.out.println("requete fermée avec succès"); requete.close(); } catch(Exception e) { System.out.println("Erreur de fermeture d'une requète"); } } } // Ferme une connexion public static void closeConnection(Connection connexion) { if(connexion!=null) { try { System.out.println("connexion fermée avec succès"); connexion.close(); } catch(Exception e) { System.out.println("Erreur de fermerture d'une connexion"); } } } } |
Cette classe nous permet de fermer notre connexion depuis nos méthodes d’accès en base.
f - Configuration du fichier web.xml
Nous allons associer la ressource jdbc (jdbcMysql) Ã la dataSource : javax.sql.DataSource

ainsi que le paramètre dataSource préfixé par java:/comp/env/

g - Configuration du fichier context.xml
Nous allons maintenant configurer le fichier context.xml que nous placerons dans le répertoire META-INF du /webContent de notre application. Ce fichier déclare les différents paramètres nécessaires à la connexion à la base de donnée. Attention renommez context en Context et ressource en Ressource
< ?xml version="1.0" encoding="UTF-8"?> <context docBase="ProjectName" path="/ProjectName" reloadable="true" source="org.eclipse.jst.jee.server:apiBlog" > <resource name="jdbcMysql" auth="Container" type="javax.sql.DataSource" username="root" password="" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/login" maxActive="20" maxIdle="10" validationQuery="SELECT 1" /> </context> |
c
4 – Notre projet Finalisé.
Il doit ressemblé à ceci :
Vous pouvez télécharger les sources de ce projet ici.











avril 14th, 2010 at 4 h 37 min
[...] Ce billet était mentionné sur Twitter par altenide et Lionel LOKO, Mathieu Breton. Mathieu Breton a dit: Apprendre #Struts2 http://bit.ly/cAd6ut , http://bit.ly/aIfxGw , http://bit.ly/a3eWjK #Tutoriel #Debutant [...]
avril 15th, 2010 at 15 h 50 min
[...] Ce tutoriel a pour but de vous initier à Ajax et Dojo dans un environnement MVC2 avec le framework Struts 2. Je vous recommande avant de commencer de réaliser le tutoriel l’accès au base de données SQL avec struts 2 [...]