Introduction Dozer

De Wiki de Romain RUDIGER
Aller à : navigation, rechercher

Présentation

Dozer est un utilitaire de mapping de JavaBean, il permet de convertir des objets complexes en d'autres objets. Il gère l'héritage, les notions d'abstraction, les collections, ...

La plupart du temps on l'utilise pour générer des DTO (Data Transfert Object) dans le but de traverser les couches : Service d'accès aux données <-> Service métier <-> IHM

Il faut noter que ces mappings sont Bi-directionnels.

Exemple

Mapping simple

Prenons le DC suivant pour illustrer cette présentation :

Diagramme de classe : Accident

Par défaut Dozer mappe les champs qui on le même nom, typiquement si on décide de mapper Accident et AccidentDto seul le champ idAccident sera valoriser.

private static void convertDemo() {
	MapperIF mapper = new DozerBeanMapper();
	Accident accident = new Accident();
	accident.setIdAccident(123);
	accident.setNbBlesse(0);
	Moto moto = new Moto();
	moto.setIdVehicule(1);
	moto.setImmatriculation("123ABC45");
	moto.setCouleur("rouge");
	Voiture voiture = new Voiture();
	voiture.setIdVehicule(2);
	voiture.setImmatriculation("678DEF90");
	voiture.setNbPlaces(5);
		
	List<Vehicule> listVehicule = new ArrayList<Vehicule>();
	listVehicule.add(moto);
	listVehicule.add(voiture);

	accident.setListVehicule(listVehicule);
	AccidentDto accidentDto = (AccidentDto) mapper.map(accident, AccidentDto.class);
}
accident	Accident
	idAccident	Integer
		value	123
	listVehicule	ArrayList<E>
		elementData	Object[10]
		modCount	2
		size	2
	nbBlesse	Integer
accidentDto	AccidentDto
	idAccident	Integer
		value	123
	listVehiculeDto	null

Mapping avancé

Pour mapper des champs différents (ou des grappes) on utilise des fichiers de mapping XML. Dans notre cas les classes Vehicule et VehiculeDto sont abstraites, il faut donc lister les éventuelles classes concrètes de Dozer peut rencontrer.

Accident-AccidentDto.xml

<?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>fr.novalan.wiki.java.entity.Accident</class-a>
		<class-b>fr.novalan.wiki.java.entity.dto.AccidentDto</class-b>
		<field>
			<a>listVehicule</a>
			<b>listVehiculeDto</b>
			<a-hint>
				fr.novalan.wiki.java.entity.Voiture,
				fr.novalan.wiki.java.entity.Moto 
			</a-hint>
			<b-hint>
				fr.novalan.wiki.java.entity.dto.VoitureDto,
				fr.novalan.wiki.java.entity.dto.MotoDto 
			</b-hint>
		</field>
	</mapping>
</mappings>

Moto-MotoDto.xml

<?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>fr.novalan.wiki.java.entity.Moto</class-a>
		<class-b>fr.novalan.wiki.java.entity.dto.MotoDto</class-b>
	</mapping>
</mappings>

Voiture-VoitureDto.xml

<?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>fr.novalan.wiki.java.entity.Voiture</class-a>
		<class-b>fr.novalan.wiki.java.entity.dto.VoitureDto</class-b>
	</mapping>
</mappings>

La classe DozerMapper permet de lister les xml à charger :

package fr.novalan.wiki.java.dozer;

import java.util.ArrayList;
import java.util.List;

import net.sf.dozer.util.mapping.DozerBeanMapper;

public class DozerMapper {

    private DozerBeanMapper mapper;

    private static DozerMapper instance;

    private DozerMapper() {
        List<String> myMappingFiles = new ArrayList<String>();
        myMappingFiles.add("Accident-AccidentDto.xml");
        myMappingFiles.add("Moto-MotoDto.xml");
        myMappingFiles.add("Voiture-VoitureDto.xml");
        mapper = new DozerBeanMapper();
        mapper.setMappingFiles(myMappingFiles);
    }

    public static DozerMapper getInstance() {
        if (instance == null) {
            instance = new DozerMapper();
        }
        return instance;
    }

    public static DozerBeanMapper getMapper() {
        return getInstance().mapper;
    }

}

La classe de test DozerMapperTest

package fr.novalan.wiki.java.dozer.test;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

import org.junit.Test;

import fr.novalan.wiki.java.dozer.DozerMapper;
import fr.novalan.wiki.java.entity.Accident;
import fr.novalan.wiki.java.entity.Moto;
import fr.novalan.wiki.java.entity.Vehicule;
import fr.novalan.wiki.java.entity.Voiture;
import fr.novalan.wiki.java.entity.dto.AccidentDto;
import fr.novalan.wiki.java.entity.dto.AccidentInfoDto;


public class DozerMapperTest extends TestCase {

	@Test
	public void testConvertAccidentToAccidentDto() {
		Accident accident = this.getBouchon();
		
		AccidentDto accidentDto = (AccidentDto) DozerMapper.getMapper().map(accident, AccidentDto.class);
		assertNotNull(accidentDto);
		assertNotNull(accidentDto.getIdAccident());
		assertNotNull(accidentDto.getListVehiculeDto());
		assertEquals(accidentDto.getListVehiculeDto().size(), 2);
	}
	
	@Test
	public void testConvertAccidentToAccidentInfoDto() {
		Accident accident = this.getBouchon();
		
		AccidentInfoDto accidentInfoDto = (AccidentInfoDto) DozerMapper.getMapper().map(accident, AccidentInfoDto.class);
		assertNotNull(accidentInfoDto);
		assertNotNull(accidentInfoDto.getIdAccident());
		assertNotNull(accidentInfoDto.getNbBlesse());
		assertNotNull(accidentInfoDto.getListVehiculeDto());
		assertEquals(accidentInfoDto.getListVehiculeDto().size(), 2);
	}
	
	private Accident getBouchon() {
		Accident accident = new Accident();
		accident.setIdAccident(123);
		accident.setNbBlesse(0);
		
		Moto moto = new Moto();
		moto.setIdVehicule(1);
		moto.setImmatriculation("123ABC45");
		moto.setCouleur("rouge");
		Voiture voiture = new Voiture();
		voiture.setIdVehicule(2);
		voiture.setImmatriculation("678DEF90");
		voiture.setNbPlaces(5);
		
		List<Vehicule> listVehicule = new ArrayList<Vehicule>();
		listVehicule.add(moto);
		listVehicule.add(voiture);
		accident.setListVehicule(listVehicule);
		return accident;
	}
}

Plugin Eclipse

Il faut également noter l'existence d'un plugin pour eclipse (v0.6.4), il nécessite l'installation de SpringIDE, pour le moment il n'apporte rien de vraiment intéressant mais la prochaine version devrait intégrer une version graphique.

Liens utiles

  • Site officiel [1]
  • Documentation [2]
  • Plugin Eclipse [3]
  • SpringIDE [4]

Rémi Rudiger 26 février 2009 à 23:18 (UTC)