Introduction à STRUTS2 par l'exemple


précédentsommairesuivant

XVII. Exemple 15 - Intégration Struts 2 / Spring

Dans l'exemple précédent, nous n'avions pas de données de portée Application partagées par toutes les requêtes de tous les utilisateurs. Nous en montrons un exemple ici. Pour le mettre en oeuvre, nous utilisons le framework Spring [http://www.springsource.org/]. Spring est un outil de très grande valeur. Nous n'en montrons dans cet exemple qu'une infime partie. Un exemple ultérieur l'utilisera plus intensivement.

Le but de cette application est d'afficher des données de portée Application.

XVII-A. Le projet Netbeans

Le projet Netbeans de l'application est le suivant :

Image non disponible
  • en [1] :
    • [web.xml] qui configure l'application web va évoluer vis à vis de ce qu'il était dans les versions précédentes
    • [applicationContext.xml] est le fichier de configuration de Spring
  • en [2] : la vue [Context.jsp] qui affichera les données de portée Application
  • en [3] :
    • le fichier des messages [messages.properties]
    • le fichier de configuration principal de Struts [struts.xml]. Va évoluer vis à vis des applications précédentes.
  • en [4] :
    • l'action Struts [Action1.java]
    • la classe [Config.java] qui va mémoriser les données de portée application
    • le fichier de configuration secondaire de Struts [example.xml]
  • en [5] : la bibliothèque Struts 2
  • en [6] :
    • les archives nécessaires à Spring [spring-core, spring-context, spring-beans, spring-web, commons-logging]
    • l'archive du plugin Spring pour Struts 2. Permet l'intégration de Spring avec Struts 2 [struts2-spring-plugin]

Vis à vis des versions précédentes :

  • il faut rajouter des archives au projet
  • modifier les fichiers [web.xml] et [struts.xml]

XVII-B. Configuration

XVII-B-1. Le fichier [web.xml]

Le fichier [web.xml] évolue comme suit :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Exemple 14</display-name>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

La modification a lieu lignes 12-14. Un listener est ajouté à l'application web. Lorsque l'application web va être lancée, la classe implémentant ce listener va être instanciée. C'est une classe de Spring. Cette classe va exploiter le fichier [WEB-INF/applicationContext.xml]. Celui-ci est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  
  <!-- configuration des beans de portée application -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

</beans>
  • le fichier de configuration de Spring a la balise racine <beans> (lignes 2 et 11). On pourrait traduire beans par objets. Spring va instancier tous les objet (bean) trouvés dans ce fichier de configuration. Il ne le fait qu'une fois, lorsque le listener Spring est lancé au démarrage de l'application web.
  • lignes 7-9 : définissent un bean nommé config (id). Le bean config est associé à la classe (class) [example.Config]. Spring va instancier cette classe.
  • ligne 8 : définit une propriété de la classe [example.Config]. Spring va appeler la méthode [example.Config].setNbMaxUsers(10). Il faut donc que la méthode setNbMaxUsers existe dans la classe. Celle-ci est la suivante :
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
package example;

public class Config {

  private int nbMaxUsers;

  public int getNbMaxUsers() {
    return nbMaxUsers;
  }

  public void setNbMaxUsers(int nbMaxUsers) {
    this.nbMaxUsers = nbMaxUsers;
  }
  
}

Cette classe ne définit qu'un champ nbMaxUsers avec ses get et set. Si on a bien suivi ce qui a été dit, au démarrage de l'application web, une instance de la classe [Config] est instanciée avec la valeur 10 pour son champ nbMaxUsers. Nous n'avons défini qu'un unique champ mais c'est suffisant pour notre démonstration. Nous voulons montrer que ce champ, qui pourrait représenter un nombre maximal d'utilisateurs, est une donnée de portée Application accessible à toutes les actions. C'est ce que nous montrerons avec l'action [Action1].

XVII-B-2. Le fichier [struts.xml]

Le fichier de configuration principal de Struts est le suivant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
  <!-- internationalisation -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- intégration Spring -->
  <constant name="struts.objectFactory.spring.autoWire" value="name" />

  <include file="example/example.xml"/>

  <package name="default" namespace="/" extends="struts-default">
    <default-action-ref name="index" />
    <action name="index">
      <result type="redirectAction">
        <param name="actionName">Action1</param>
        <param name="namespace">/example</param>
      </result>
    </action>
  </package>

</struts>

Seule la ligne 10 est différente des versions précédentes de ce fichier. Elle définit une constante Struts. Les objets instanciés par Spring peuvent être injectés dans d'autres objets. C'est le fondement même de Spring. Ici une référence sur l'objet de type [Config] créé par Spring va pouvoir être injecté dans des objets Struts. C'est là qu'intervient le plugin Spring pour Struts 2 qui assure l'intégration de Spring par Struts.

La ligne 10 indique que l'injection d'objets Spring dans un objet Struts se fera de façon automatique (autowire) par nom (value). Revenons au fichier de configuration [applicationContext.xml] :

 
Sélectionnez
1.
2.
3.
4.
<!-- configuration des beans de portée application -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

Ce que Struts 2 appelle le nom du bean est en fait l'id. Donc ici, le bean de type [Config] instancié a pour nom config.

L'action [Action1.java] est la suivante :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
package example;

import com.opensymphony.xwork2.ActionSupport;
...
public class Action1 extends ActionSupport implements SessionAware, RequestAware, ParameterAware {

  // constructeur sans paramètre
  public Action1() {
  }
  
  // Session, Request, Parametres
  private Map<String, Object> session;
  private Map<String, Object> request;
  private Map<String, String[]> parameters;
  private Config config;

  @Override
  public String execute() {
  ....
    // requête
    request.put("nbMaxUsers", config.getNbMaxUsers());

    // affichage page JSP
    return SUCCESS;
  }
...
  public Config getConfig() {
    return config;
  }

  public void setConfig(Config config) {
    this.config = config;
  }
}

L'action [Action1] est identique à ce qu'elle était dans l'application précédente aux détails près suivants :

  • ligne 15 : un champ config a été ajouté. Parce qu'il porte le nom d'un bean instancié par Spring, ce champ recevra automatiquement une référence sur cet objet. Ainsi l'action a accès à la configuration de l'application ou plus généralemet aux données de portée Application.
  • ligne 31 : Spring instanciera le champ config via sa méthode set. Elle doit donc être présente.
  • ligne 21 : l'action accède aux informations de portée Application. On met le nombre maximal d'utilisateurs nbMaxUsers dans la requête afin que la vue [Context.jsp] puisse l'afficher.

XVII-B-3. Le fichier [example.xml]

Le fichier secondaire de configuration de Struts est identique à celui de la version précédente :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
  <package name="example" namespace="/example" extends="struts-default">
    <action name="Action1" class="example.Action1">
      <result name="success">/example/Context.jsp</result>
    </action>
  </package>
</struts>

XVII-C. La vue [Context.jsp]

La vue [Context.jsp] est la suivante :

 
Sélectionnez
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title><s:text name="Context.titre"/></title>
    <s:head/>
  </head>

  <body background="<s:url value="/ressources/standard.jpg"/>">
    <h2><s:text name="Context.message"/></h2>
    <h3><s:text name="Context.parameters"/></h3>
    nom : <s:property value="#parameters['nom']"/><br/>
    age : <s:property value="#parameters['age']"/>
    <h3><s:text name="Context.session"/></h3>
    compteur : <s:property value="#session['compteur']"/>
    <h3><s:text name="Context.request"/></h3>
    nbMaxUsers : <s:property value="#request['nbMaxUsers']"/>
  </body>
</html>

XVII-D. Les tests

Un exemple d'exécution est le suivant :

Image non disponible


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 Serge Tahe. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.