1

Dozerを使用してのインスタンスを変換しようとしています

class Source {
  private List<Foo> foos = new ArrayList<Foo>();

  public List<Foo> getFoos() {
    return foos;
  }

  public void setFoos(List<Foo> foos) {
    this.foos = foos;
  }
}

次のインスタンスに:

class Target {
  private List<Foo> foos = new ArrayList<Foo>();

  public List<Foo> getFoos() {
    return foos;
  }
}

Javaコードでは、このような会話を実行します

Source s = new Source();
Target t = new Target();
t.getFoos().addAll(s.getFoos());

プロパティ(ゲッターのみ)Targetがないため、Dozerはデフォルトではこの変換を実行しません。foos

実際には、マップする必要のあるこのようなプロパティがたくさんあります。1つのオプションは、プライベートフィールドを直接マップするようにDozerに指示することですが、これは完全に満足のいくものではありません。理由は次のとおりです。

  • Dozer XML構成で、この方法でマップする各フィールドを名前で指定する必要があります
  • プライベートフィールドへのアクセスは悪い

もっと良い方法はありますか?

4

4 に答える 4

1

is-accessibleフラグ以外にこれを回避する簡単な方法はありません。ただし、ゲッターを使用して実行するカスタム コンバーターを定義することもできます。

t.getFoos().addAll(s.getFoos());

これは非常に手間がかかり、多くの作業になります。とセッターの代わりにゲッターを使用するカスタム コンバーター ( http://dozer.sourceforge.net/documentation/customconverter.htmlを参照)を定義する必要があります。SourceTarget

public class TestCustomConverter implements CustomConverter {

  public Object convert(Object destination, Object source, Class destClass, Class sourceClass) {
    if (source == null) {
      return null;
    }
    if (source instanceof Source) {
      Target dest = null;
      // check to see if the object already exists
      if (destination == null) {
        dest = new Target();
      } else {
        dest = (Target) destination;
      }
      dest.getFoos().addAll(((Source)source).getFoos());
      return dest;
    } else if (source instanceof Target) {
      Source dest = null;
      // check to see if the object already exists
      if (destination == null) {
        dest = new Source();
      } else {
        dest = (Source) destination;
      }
      dest.setFoos(((Target)source).getFoos());
      return dest;
    } else {
      throw new MappingException("Converter TestCustomConverter used incorrectly. Arguments passed in were:"
          + destination + " and " + source);
    }
  } 

幸運を祈ります

于 2011-04-21T14:09:51.107 に答える
1

Dozer の代わりにModelMapperをチェックしてみてください。このシナリオの処理は簡単です。

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
  .enableFieldMatching(true)
  .setFieldAccessLevel(AccessLevel.PRIVATE);

これにより、すべてのプライベート フィールドのフィールド マッチングが有効になりました。マッピングを実行するには:

Target target = modelMapper.map(source, Target.class);

詳細については、ModelMapper サイトをご覧ください。

http://modelmapper.org

于 2011-06-24T04:44:59.800 に答える
1

メソッドを Target に追加できます。

public void addFoo(Foo item) {
    foos.add(item);
}

<mapping>
  <class-a>Source</class-a>
  <class-b>Target</class-b>
  <field>
    <a>foos</a>
    <b set-method="addFoo" type="iterate">foos</b>
  </field>
</mapping>

セッターまたはゲッター式でELを使用できるようにする機能を提案するかもしれません

于 2011-05-29T20:56:30.383 に答える