2017-02-14 62 views
0

由於這個麻煩,我掙扎了兩天,我無法得到它。我有:如何將集合中包含的對象映射到字段並反之亦然?推土機

public class ClientBo{ 
    ... 
    List<PersonBo> person; 
    ... 
} 

public class ClientVo{ 
    ... 
    PersonVo person; 
    ... 
} 

我需要做的就是配置莫名其妙推土機,這樣我就可以從PersonBo的列表映射到單場PersonVo(VO的博具有相同的字段名) 。

推土機的功能可以從集合轉換爲單個字段,而不是其他方式。 http://dozer.sourceforge.net/documentation/faq.html#mult-fields-to-single-field

,我想通了,唯一的解決辦法是:

<mapping type="one-way"> 
    <class-a>...ClientBo</class-a> 
    <class-b>...ClientVo</class-b> 
    <field> 
     <a>person[0]</a> 
     <b>person</b> 
    </field> 
</mapping> 
<mapping type="one-way"> 
    <class-a>...ClientVo</class-a> 
    <class-b>...ClientBo</class-b> 
    <field custom-converter="mapper.CustomObjectToList"> 
     <a>person</a> 
     <b>person</b> 
    </field> 
</mapping> 

public class CustomObjectToList implements CustomConverter{ 

     public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) { 
      if(sourceFieldValue==null) 
       return null; 

      if(sourceFieldValue instanceof List && ((List<?>) sourceFieldValue).size()>0){ 
       /* This if is an attempt to get the first element of the 
       list and return it as a single field, but id doesn't work*/ 
       Object o = ((List<?>)sourceFieldValue).get(0); 
       return o; 


      }else{ 
       /*Here a single field is put in a List and returned*/ 
       ArrayList<Object> result = new ArrayList<>(); 
       result.add(sourceFieldValue); 
       return result; 
      } 
     } 
    } 

有沒有什麼辦法讓我可以刪除

<mapping type="one-way"> 
     <class-a>...ClientBo</class-a> 
     <class-b>...ClientVo</class-b> 
     <field> 
      <a>person[0]</a> 
      <b>person</b> 
     </field> 
    </mapping> 

,並把工作做好由一個自定義轉換器?它應該儘可能通用,因此它可以適用於類似的環境。

謝謝!

回答

1

1.您是否嘗試測試您的CustomConverter?

因爲如果你試圖打印出任何變量,你會得到一個ClassCastException,像這樣:

Exception in thread "main" java.lang.ClassCastException: beans.PersonVo cannot be cast to beans.PersonBo 
    at execute.Execute.main(Execute.java:37) 

是,具有相同名稱的領域確實會自動映射,但在你的情況是使用CustomConverter進行映射。換句話說,Dozer相信你會照顧它,所以你不能簡單地將一個Class變量(personVo)指向另一個不相關的Class實例(personBo)。

2.糾正上述異常

糾正上述異常的最簡單方法是使用setter和getter方法,就像您對任何不相關的類:

public class CustomObjectToList implements CustomConverter{ 

public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) { 
    if(sourceFieldValue==null) 
     return null; 

    if(sourceFieldValue instanceof List && ((List<?>) sourceFieldValue).size()>0){ 
     /* This if is an attempt to get the first element of the 
     list and return it as a single field, but id doesn't work*/ 
     Object o = ((List<?>)sourceFieldValue).get(0); 
     return o; 


    }else{ 
     /*Updated: using a setter and getter*/ 
     PersonVo source = (PersonVo) sourceFieldValue; 
     List<PersonBo> dest = new ArrayList<PersonBo>(); 

     PersonBo bo = new PersonBo(); 
     bo.setName(source.getName()); 
     dest.add(bo); 
     return dest; 
    } 
} 
} 

3.回答您的問題

要取消單向映射並僅使用CustomConverter,可以使用以下代碼:

推土機XML:

<!-- <mapping type="one-way"> 
    <class-a>beans.ClientBo</class-a> 
    <class-b>beans.ClientVo</class-b> 
    <field> 
     <a>person[0]</a> 
     <b>person</b> 
    </field> 
</mapping> --> 
<mapping> 
    <class-a>beans.ClientVo</class-a> 
    <class-b>beans.ClientBo</class-b> 
    <field custom-converter="converter.CustomObjectToList"> 
     <a>person</a> 
     <b>person</b> 
    </field> 
</mapping> 

CustomConverter:

public class CustomObjectToList implements CustomConverter{ 

public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) { 
     if(sourceFieldValue==null) 
      return null; 

     if(sourceFieldValue instanceof PersonVo){ 
      PersonVo source = (PersonVo) sourceFieldValue; 
      List<PersonBo> dest = new ArrayList<PersonBo>(); 

      PersonBo bo = new PersonBo(); 
      bo.setName(source.getName()); 
      dest.add(bo); 
      return dest; 

     }else if (sourceFieldValue instanceof List<?>){ 
      List<PersonBo> source = (List<PersonBo>) sourceFieldValue; 

      PersonVo dest = new PersonVo(); 
      dest.setName(source.get(0).getName()); 
      return dest; 
     } 
     else { 
      throw new MappingException("Converter TestCustomConverter " 
       + "used incorrectly. Arguments passed in were:" 
       + existingDestinationFieldValue + " and " + sourceFieldValue); 
      } 
    } 
}