Webアプリケーションにおいて、異なるレイヤ間で、データの受け渡しをする場合など、Beanマッピングが必要となるケースは多いです。その時に、Dozerを使用することで下図のように、変換元のBeanから変換先のBeanに、再帰的に値をコピーし、コピー元JavaBeanとコピー先JavaBeanで異なるフィールド名、異なるデータ型のコピーも容易に行うことができます。
Dozerライブラリのダウンロード(https://sourceforge.net/projects/dozer/files/dozer/5.3.2/)
#使い方
1.コピー元とコピー先JavaBeanの例
// コピー元JavaBean
public class SourceBean implements Serializable {
private String productId;
private int productPrice;
private String productionDate;
private byte[] productImage;
private List<String> shopList;
// getter、setter省略
}
// コピー先JavaBean
public class DestinationBean {
private String productId;
private int price;
private Timestamp date;
private String productImage;
private String[] shopList;
// getter、setter省略
}
2.DozerのBean定義を作成する。
<!-- Dozerの設定 -->
<bean name="dozer" class="org.dozer.spring.DozerBeanMapperFactoryBean">
<property name="mappingFiles" value="classpath*:/META-INF/dozer/*-mapping.xml" />
</bean>
3.Dozerユーティルを使用し、Beanマッピングを行う。
@Resource
private DozerBeanMapper dozer;
public void execute(SourceBean sb) {
// JavaBeanのマッピング
DestinationBean dBean = dozer.map(sb, DestinationBean.class);
}
##データ型は同じ、フィールド名が異なる場合のマッピング
フィールド名が異なる場合、マッピング定義XMLファイルを作成し、Beanマッピングするフィールドを定義することで変換できます。
・コピー元フィールドproductPrice
・コピー先フィールドprice
;
META-INF/dozerフォルダ内に、マッピング定義XMLファイル「dozer-mapping.xml」を作成します。
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mapping>
<class-a>bean.SourceBean</class-a> <!-- コピー元JavaBean -->
<class-b>bean.DestinationBean</class-b> <!-- コピー先JavaBean -->
<field>
<a>productPrice</a> <!-- コピー元フィールド -->
<b>price</b> <!-- コピー先フィールド -->
</field>
</mapping>
</mappings>
##フィールド名は同じ、データ型が異なる場合のマッピング
フィールドの型が異なる場合、型変換がサポートされている型は、自動でマッピングできます。
例 : Date-> Timestamp
※自動変換のサポートについては、Dozerマニュアルをご参照ください。
型変換がサポートされていない型は、カスタムコンバーターを作成し、Beanマッピングを行います。
・コピー元データ型:byte[]
・コピー先データ型:String(Base64エンコード)
・コピー元データ型:String
・コピー先データ型:Timestamp
1.META-INF/dozerフォルダ内に、dozer-configration-mapping.xmlを作成する。
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<configuration>
<custom-converters>
<!--byte[]から文字列への変換-->
<converter type="util.ByteToStringConverter"> <!--コンバータークラス-->
<class-a>[B</class-a> <!--変換元データ型:byte[]-->
<class-b>java.lang.String</class-b> <!--変換先データ型:String-->
</converter>
<!--文字列からTimestampへの変換-->
<converter type="util.StringToTimestampConverter"> <!--コンバータークラス-->
<class-a>java.lang.String</class-a> <!--変換元データ型:String-->
<class-b>java.sql.Timestamp</class-b> <!--変換元データ型:Timestamp-->
</converter>
</custom-converters>
</configuration>
</mappings>
2.カスタムコンバータークラスは以下のように作成する。
・byte[]配列とBase64文字列の相互変換クラス
public class ByteToStringConverter extends DozerConverter<byte[], String> {
/**
* コンストラクタ
*/
public ByteToStringConverter() {
super(byte[].class, String.class);
}
/**
* 文字列からbyte配列への変換処理
* <p>
* 指定された文字列に対して、Base64デコード処理を行い、
* Byte配列に変換し、返却する。
* </p>
* @see org.dozer.DozerConverter#convertFrom(java.lang.Object, java.lang.Object)
*/
@Override
public byte[] convertFrom(String arg0, byte[] arg1) {
return java.util.Base64.getDecoder().decode(arg0);
}
/**
* byte配列から文字列への変換処理
* <p>
* 指定されたbyte配列に対して、Base64エンコード処理を行い、
* 文字列に変換し、返却する。
* </p>
* @see org.dozer.DozerConverter#convertTo(java.lang.Object, java.lang.Object)
*/
@Override
public String convertTo(byte[] arg0, String arg1) {
return java.util.Base64.getEncoder().encodeToString(arg0);
}
}
・文字列とTimestampの相互変換クラス
public class StringToTimestampConverter extends DozerConverter<String, Timestamp> {
/**
* コンストラクタ
*/
public StringToTimestampConverter() {
super(String.class, Timestamp.class);
}
/**
* Timestampから文字列への変換処理
*
* @see org.dozer.DozerConverter#convertFrom(java.lang.Object, java.lang.Object)
*/
@Override
public String convertFrom(Timestamp arg0, String arg1) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(arg0);
}
/**
* 文字列からTimestampへの変換処理
*
* @see org.dozer.DozerConverter#convertTo(java.lang.Object, java.lang.Object)
*/
@Override
public Timestamp convertTo(String arg0, Timestamp arg1) {
try {
return new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse(arg0).getTime());
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}