Le quatrième billet dans la série sur Les bonnes pratiques avec Struts.

Introduction

Struts se révèle très pratique pour gérer les formulaires. En effet, il s’occupe de charger les données du formulaire pour l’afficher. Et il récupère les données dans la requête lorsqu’un formulaire est validé.

Côté code Java, cela se traduit par la manipulation de Java beans héritant de la classe ActionForm. Lors de l’appel à la couche métier, il est alors souvent nécessaire de transférer les données un formulaire vers un objet métier (le processus inverse est valable). Cette étape consiste à créer un objet métier, puis à faire appel successif aux getters du formulaire et aux setters de l’objet métier.

Pour être honnête, l’écriture de code n’est pas passionnant, prend de la place et doit être maintenu sérieusement lorsque des champs sont ajoutés ou supprimés.

Solutions

Heureusement pour les utilisateurs de Struts, il existe des outils pour automatiser cette procédure de transfert de données des objets de la vue vers les objets du domaine ou du métier.

BeanUtils

BeanUtils est une bibliothèque fournie par le projet Jakarta qui permet de manipuler simplement des Java beans. Struts l’utilise entre autre pour peupler les formulaires.

Avec BeanUtils, il est possible de copier les données d’un objet source vers un objet destination même s’ils n’ont pas la même classe. Par contre, seuls les attributs ayant les mêmes noms sont copiés.

Exemple de code :

SourceClass srcObject = new SourceClass();
//chargement les données de src
Object DestinationClass dstObject = new DestinationClass();
BeanUtils.copyProperties(dstObject, srcObject);

Dozer

Dozer est qualifié de framework de mapping objet-objet. Concrêtement, il permet de faire du mapping entre des objets de classes différentes. Donc, par exemple entre un objet de formulaire et un objet métier.

Là où Dozer devient intéressant, c’est que ce mapping est configurable et surtout supporte les objets imbriqués (objets en tant qu’attributs). Ainsi, les deux objets utilisés pour une copie ne sont pas obligé d’avoir des attributs avec les mêmes noms. Ils ne sont pas obligés non plus d’avoir la même structure.

Exemple de code :

SourceClass srcObject = new SourceClass();
//chargement les données de src
Object MapperIF mapper = new DozerBeanMapper();
DestinationClass dstObject = (DestinationClass) mapper.map(srcObject, DestinationClass.class);

Exemple de mapping pour faire correspondre les champs login et pwd avec les champs userName et password :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mappings PUBLIC "-//DOZER//DTD MAPPINGS//EN"    "http://dozer.sourceforge.net/dtd/dozerbeanmapping.dtd">
<mappings>
	<mapping>
 		<class-a>com.company.project.SourceClass</class-a>
  		<class-b>com.company.project.DestinationClass</class-b>
	  	<field>
 			<a>login</a>
 			<b>userName</b>
	 	</field>
	 	<field>
 			<a>pwd</a>
 			<b>password</b>
	 	</field>
	</mapping>
</mappings>

Exemple de mapping pour faire correspondre les champs commençant par address avec les champs respectifs de l’attribut address :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mappings PUBLIC "-//DOZER//DTD MAPPINGS//EN"    "http://dozer.sourceforge.net/dtd/dozerbeanmapping.dtd">
<mappings>
	<mapping>
		<class-a>com.company.project.SourceClass</class-a>
		<class-b>com.company.project.DestinationClass</class-b>
		<field>
			<a>addressStreet</a>
			<b>address.street</b>
		</field>
		<field>
			<a>addressCity</a>
			<b>address.city</b>
		</field>
	</mapping>
</mappings>

Conclusion

Dans la plupart des cas, BeanUtils est amplement suffisant. De plus, il est directement intégré dans Struts et ne nécessite pas l’installation de bibliothèque externe pour un projet.

Cependant, il arrive que l’objet représentant un formulaire ne soit pas proche dans sa structure à l’objet métier ou aux objets métiers utilisés. Dans ce cas, Dozer se révèle être un puissant outil !

Ces outils permettent également de formater (convertir) les données brutes du formulaire pour les objets métiers.