22


6

私は何かをしたいのですが。

ArrayListオブジェクト= new ArrayList();
...
DozerBeanMapper MAPPER = new DozerBeanMapper();
...
ArrayList newObjects = MAPPER.map(objects、...);

と仮定します。

com.me.CustomObject com.me.NewObject id id2

私は試した :

ArrayListホルダー= new ArrayList(); MAPPER.map(オブジェクト、ホルダー);

しかし、ホルダーオブジェクトは空です。 私はまた運なしで第二引数を変えて遊んだ…

8 Answer


30


引用するには:

"ネストされたコレクションは自動的に処理されますが、トップレベルのコレクションを繰り返す必要があることは間違いありません。 現在のところ、これを処理するためのより洗練された方法はありません。」

http://sourceforge.net/projects/dozer/forums/forum/452530/topic/3017095[誰かがあなたのコードベースでループ構造を使わずにそれをする方法を考え出しました]、しかし私はそれがただもっと簡単で(そしてもっと読みやすい)と思いますそれをあなたのコードに入れることができます。 うまくいけば、彼らはこの能力を後で追加するでしょう。


9


私は同様の問題に直面し、そして私がそのようなマッピングを実行する必要がある度に繰り返すことを避けるために一般的な効用方法を使うことに決めました。

パブリックスタティックリストマップ(ファイナルマッパーマッパー、ファイナルリストソース、ファイナルクラスdestType){

final List dest = new ArrayList <>();

for(T要素:ソース){dest.add(mapper.map(element、destType)); }

destを返します。 }

使い方は次のようになります。

最終リストアカウント..... final List actual = Util.map(mapper、accounts、NewObject.class);

おそらくこれはさらに単純化できます。


5


何が起こっているのはあなたがタイプ消去に噛まれているということです。 実行時に、javaは ArrayList.class`だけを見ます。 `CustomObject`と NewObject`の型がないので、Dozerはあなたの CustomObject`ではなく java.util.ArrayList`を `NewObject`にマッピングしようとしています。

何が動作するはずです(まったくテストされていません)。

リストori = new ArrayList();リストn = new ArrayList(); for(CustomObject co:ori){n.add(MAPPER.map(co、CustomObject.class)); }


3


あなたはこれのようにそれをすることができます:

public List mapListObjectToListNewObject(Listオブジェクト、クラスnewObjectClass){final List newObjects = new ArrayList(); for(S s:オブジェクト){newObjects.add(mapper.map(s、newObjectClass)); newObjectsを返します。

}

そしてそれを使う:

ArrayListオブジェクト= .... リストnewObjects = mapListObjectToListNewObject(objects、NewObject.class);


2


そのユースケースのために私はかつて小さなヘルパークラスを書きました:

import java.util.Collection;

/ **
 *  ブルドーザーマッピングでトップレベルコレクションをラッピングするためのヘルパークラス。
 *  @作者Michael Ebert
 *  @param * / public final class TopLevelCollectionWrapper {

プライベートファイナルコレクションコレクション。

/ **
     *  プライベートコンストラクタ {@link #of(Collection)}で新しいインスタンスを作成してください。
     *  @see {@link #of(Collection)}
     *  @paramコレクション* / private TopLevelCollectionWrapper(最終コレクションコレクション){this.collection = collection; }

/ **
     *  ラップされたコレクションを返します* / public Collection getCollection(){return collection;} }

/ **
     *  {@link TopLevelCollectionWrapper}の新しいインスタンスを作成します。
     *  @param
     *  {@link Collection}要素のジェネリック型。
     *  @パラメータコレクション
     *  {@linkコレクション}
     *  @return {@link TopLevelCollectionWrapper} * / public static TopLevelCollectionWrapper of(final Collectionコレクション){return TopLevelCollectionWrapper(collection); }}

その後、以下の方法でdozerを呼び出します。

プライベートマッパーマッパー。

@SuppressWarnings( "未チェック")public Collection getMappedCollection(最終のCollectionコレクション){TopLevelCollectionWrapper wrapper = mapper.map(TopLevelCollectionWrapper.of(collection)、TopLevelCollectionWrapper.class);

wrapper.getCollection()を返します。 }

唯一の欠点:Dozers Mapperインターフェースがジェネリック型を扱っていないため、 `mapper.map(…​)`に「未チェック」の警告が表示されます。


2


私はJava 8とdozer 5.5を使ってそれをやった。 マッピングにXMLファイルは必要ありません。 あなたはJavaでそれをすることができます。

リストに追加のマッピングは必要ありません、必要なのはそれだけです。

マッピングのフィールドとしてリストを追加する必要があります

  1. 以下のサンプルBean設定を参照してください。

Spring設定クラス

@ConfigurationパブリッククラスConfig {

@Bean public DozerBeanMapper dozerBeanMapper()は例外をスローします{DozerBeanMapper mapper = new DozerBeanMapper();} mapper.addMapping(new BeanMappingBuilder(){@Override protected void configure(){mapping(Answer.class、AnswerDTO.class); mapping(QuestionAndAnswer.class、QuestionAndAnswerDTO.class).fields( "Answers"、 "Answers"); ;}});マッパーを返します。 }

}
パブリッククラスAnswerDTO {

パブリックAnswerDTO(){super(); }

protected int id;保護された文字列値。

//セッターとゲッター}
パブリッククラスQuestionAndAnswerDTO {

保護された文字列の質問。保護されたリストの回答。

//セッターとゲッター}

QuestionAndAnswerDTO

@Autowired private DozerBeanMapper dozerBeanMapper;
// in your method

QuestionAndAnswerDTO questionAndAnswerDTO = dozerBeanMapper.map(questionAndAnswer、QuestionAndAnswerDTO.class);

誰かがXMLの代わりにJavaのアプローチに従うのを助けることを願っています。


1


http://code.google.com/p/guava-libraries/[Guava]のおかげで実現できるシンタックスシュガーのようなもので、実際には改善されていません(そしておそらくhttp:// commonsでも同様のことが可能です)。 apache.org/ [Apache Commons]):
final List mapped = Lists.newArrayList(Iterables.transform(inputList、new Function(){public MyPojo apply(final MyEntity arg){mapmap.map(arg、MyPojo.class);}}));

他の回答で示唆されているように、これは一般的な関数に変えることもできます。


1


あなたはdozerマッパーを拡張するあなた自身のマッパークラスを実装することができます。 例:ブルドーザーマッパーに追加のメソッドを追加するインターフェースを作成します。

パブリックインタフェースMapperはorg.dozer.Mapper {List mapAsList(Iterable <?> sources、Class destinationClass);を拡張します。 }

次のステップ:上記のインターフェースを実装することによってあなた自身のMapperクラスを書きなさい。

実装クラスに下記のメソッドを追加します。

パブリッククラスMyMapperはMapperを実装しています。 for(Object source:sources){targets.add(map(source、destinationClass));ターゲットを返します。 //他のオーバーライドされたメソッド }

お役に立てれば