LoginSignup
14
19

More than 5 years have passed since last update.

Dozerライブラリを利用し、JavaBeanのマッピングを実現する。

Posted at

Webアプリケーションにおいて、異なるレイヤ間で、データの受け渡しをする場合など、Beanマッピングが必要となるケースは多いです。その時に、Dozerを使用することで下図のように、変換元のBeanから変換先のBeanに、再帰的に値をコピーし、コピー元JavaBeanとコピー先JavaBeanで異なるフィールド名、異なるデータ型のコピーも容易に行うことができます。
2016-06-30_152457.png

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);
        }
    }
}

14
19
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
19