Navigation

Struts2, Spring 2 sans XML

Un article de ODcWiki.

Jump to: navigation, search
Image:Auteur.png Auteur : gquintana.


Autrefois Struts et Spring nécessitaient des fichiers de configuration XML qui avaient tendance à rapidement prendre de l'embonpoint. Nous verrons dans cet article comment tirer partie des progrès réalisés dans Struts 2.1 et Spring 2.5 pour remplacer le XML par des annotations.

Sommaire

Librairies nécessaires

Les librairies suivantes seront placées dans le dossier WEB-INF/lib (merci Maven)

+- org.springframework:spring-web:jar:2.5.6
|  +- commons-logging:commons-logging:jar:1.1.1
|  +- org.springframework:spring-beans:jar:2.5.6
|  +- org.springframework:spring-context:jar:2.5.6
|  |  \- aopalliance:aopalliance:jar:1.0
|  \- org.springframework:spring-core:jar:2.5.6
+- org.apache.struts:struts2-core:jar:2.1.8
|  +- com.opensymphony:xwork-core:jar:2.1.6
|  +- ognl:ognl:jar:2.7.3
|  +- commons-fileupload:commons-fileupload:jar:1.2.1
|  \- commons-io:commons-io:jar:1.3.2
+- org.apache.struts:struts2-convention-plugin:jar:2.1.8
\- org.apache.struts:struts2-spring-plugin:jar:2.1.8

En plus de Struts 2.1 et Spring 2.5, on ajoute de plugin Struts2:

  • Le plugin Convention permet la déclaration des actions Struts par convention de nommage et par utilisation d'annotations Java 5. Il remplace les anciens plugins Zeroconf et Codebehind.
  • Le plugin Spring établit un lien entre Struts et Spring

Descripteur de WebApp

Le descripteur de déploiement de l'application Web (WEB-INF/web.xml) reste très simple:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
	xmlns="http://java.sun.com/xml/ns/javaee" 
	>
	<listener>
		<display-name>Spring Web Context Loader Listener</display-name>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<filter>
		<filter-name>Struts2Filter</filter-name>
		<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>Struts2Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

Nous avons:

  • Le listener <tt>ContextLoaderListener de Spring qui initialise le conteneur au démarrage de l'application
  • Le filter FilterDispatcher de Struts qui va prendre en charge les requêtes HTTP et les affecter à la bonne action (front controller).

Configuration Struts

Dans le cadre d'une utilisation classique de Struts2, le fichier de configuration struts.xml contiendrait la liste exhaustive des actions et de leurs resultats. Ici, ce fichier qui se trouve dans WEB-INF/classes ne contient que des constantes:

<?xml version="1.0" encoding="UTF-8" ?>
<struts>
	<constant name="struts.objectFactory" value="spring" />
	<constant name="struts.convention.action.packages" value="com.objetdirect.demo.springstruts2" />
	<constant name="struts.convention.action.suffix" value="Action" />
	<constant name="struts.convention.action.mapAllMatches" value="true" />
</struts>

La propriété struts.objectFactory stipule que les actions Struts seront fabriquées par la BeanFactory Spring, on pourra ainsi utiliser l'injection de dépendances pour récupérer des DAOs ou des services métiers dans les contrôleurs.

Les propriétés struts.convention.action.* configurent le plugin Convention de Struts2 pour lui indiquer où chercher des contrôleurs. Ici, ils auront le suffixe Action.

Configuration Spring

Le fichier de configuration Spring applicationContext.xml qui se trouve dans WEB-INF est lui aussi réduit au strict minimum:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	>
	<context:component-scan base-package="com.objetdirect.demo.springstruts2"/>
</beans>

La balise component-scan indique à Spring ou chercher des beans.

Contrôleur Struts

Le contrôleur est un simple objet Java :

@Component("thingListAction")
public class ThingListAction  {
	@Autowired
	private ThingDao thingDao;
	private List<Thing> things;
	public void setThings(List<Thing> things) {
		this.things = things;
	}
	public List<Thing> getThings() {
		return things;
	}
	
	@Action(value="/thingList",results={
			@Result(name="success",location="thingList.jsp")
	})
	public String listThings() {
		setThings(thingDao.getThings());
		return "success";
	}
}

C'est à la fois:

  • Un bean Spring (d'où l'annotation @Component) qui bénéficie de l'injection de dépendances (d'où l'annotation @Autowired)
  • Un contrôleur Struts (d'où les annotations @Action et @Result) composite: Il est capable de prendre en charge plusieurs URL, en ajoutant juste des méthodes dans la classe.

Cet objet est un POJO, il n'étend même pas une classe ou une interface particulière. Contrairement au précédentes versions, tester de manière unitaire un contrôleur devient un jeu d'enfants.

Vue/Page JSP

La vue est une page JSP que l'on a élu dans le contrôleur avec l'annotation @Result. Par défaut, le plugin Struts2 Convention cherche les JSP dans le dossier WEB-INF/content:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Things</title>
</head>
<body>
<h1>Things</h1>
<table>
	<thead>
		<tr>
			<th>Id</th>
			<th>Name</th>
			<th>Actions</th>
		</tr>
	</thead>
	<tbody>
		<s:iterator var="thing" value="things">
			<tr>
				<td><s:property value="id" /></td>
				<td><s:property value="name" /></td>
			</tr>
		</s:iterator>
	</tbody>
</table>
</body>
</html>

La JSP s'appuie sur la taglib Struts2.

Boîte à outils
Dernière modification de cette page le 25 janvier 2010 à 09:42