2011-11-25 138 views
15

我有這樣的枚舉:推土機字符串枚舉映射

public enum PartnershipIndicator { 
    VENDOR("VENDOR"), COPARTNER("COPARTNER"), BUYER("BUYER"); 

    String code; 

    private PartnershipIndicator(String code) { 
     this.code = code; 
    } 

    public String getCode() { 
     return code; 
    } 

    public static PartnershipIndicator valueOfCode(String code) { 
     for (PartnershipIndicator status : values()) { 
      if (status.getCode().equals(code)) { 
       return status; 
      } 
     } 
     throw new IllegalArgumentException(
      "Partnership status cannot be resolved for code " + code); 
    } 

    @Override 
    public String toString() { 
     return code; 
    } 
} 

我需要將其轉換爲字符串,反之亦然。 現在,它由自定義轉換器完成。但我想通過推土機映射來做到這一點(如果可能的話)。如果我不寫任何映射到推土機confing,我得到

org.dozer.MappingException: java.lang.NoSuchMethodException: by.dev.madhead.demo.test_java.model.PartnershipIndicator.<init>() 

例外。我不能添加默認的公共構造函數枚舉,因爲它是不可能的。所以,我用內部代碼和valueOfCode()/ toString()寫了一個技巧。這是行不通的。然後,我已將其映射到推土機配置中:

<mapping> 
    <class-a>java.lang.String</class-a> 
    <class-b create-method="valueOfCode">by.dev.madhead.demo.test_java.model.PartnershipIndicator</class-b> 
</mapping> 

它不起作用。我嘗試了valueOfCode(),單向映射。什麼都沒有枚舉到字符串轉換不起作用,我得到空字符串。 任何想法?

+1

我已將自定義轉換器添加到推土機主控。所以沒有人從5.4不會面臨這個問題:) – madhead

+0

@all任何人都可以看看這個[問題](http://stackoverflow.com/questions/27864640/dozer-string-to-date-field-level-mapping-for -al-list) – 09Q71AO534

回答

19

不知道這是否仍然是一個問題,但可能有助於任何人搜索。但是這裏實現的解決方案如下:

@Override 
public Object convert(Object destination, Object source, Class<?> destinationClass, Class<?> sourceClass) { 
    if(source == null) 
     return null; 
    if(destinationClass != null){ 
     if(destinationClass.getSimpleName().equalsIgnoreCase("String")){ 
      return this.getString(source); 
     }else if(destinationClass.isEnum()){ 

      return this.getEnum(destinationClass, source); 

     }else{ 
      throw new MappingException(new StrBuilder("Converter ").append(this.getClass().getSimpleName()) 
         .append(" was used incorrectly. Arguments were: ") 
         .append(destinationClass.getClass().getName()) 
         .append(" and ") 
         .append(source).toString()); 
     } 
    } 
    return null; 
} 

private Object getString(Object object){ 
    String value = object.toString(); 
    return value; 
} 
private Object getEnum(Class<?> destinationClass, Object source){ 
    Object enumeration = null; 

    Method [] ms = destinationClass.getMethods(); 
    for(Method m : ms){ 
     if(m.getName().equalsIgnoreCase("valueOf")){ 
      try { 
       enumeration = m.invoke(destinationClass.getClass(), (String)source); 
      } 
      catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } 
      catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } 
      catch (InvocationTargetException e) { 
       e.printStackTrace(); 
      } 
      return enumeration; 
     } 
    } 
    return null; 
} 

構建異常消息時的StrBuilder類來自apaches common-lang libs。但除此之外,一個簡單的反思來解決這個問題。只需添加到實現CustomConverter,然後在推土機映射XML文件中添加以下配置類:

<configuration> 
    <custom-converters> 
     <converter type="com.yourcompany.manager.utils.dozer.converters.EnumStringBiDirectionalDozerConverter"> 
      <class-a>java.lang.Enum</class-a> 
      <class-b>java.lang.String</class-b> 
     </converter> 
    </custom-converters> 
</configuration> 

注意,您可以只列出的配置,一旦你所有的映射文件之間(如果您有多個),否則推土機會抱怨。我通常做的是將我的自定義轉換器配置放在一個文件中以簡化操作。希望這可以幫助!

4

Dozer中沒有默認的字符串映射枚舉。請參閱Dozer文檔中的Data type conversion。所以你有兩種選擇:

  • 你可以寫一個自定義的轉換器,使用泛型來處理任何枚舉。
  • 或者,您可以將修補程序提交給Dozer以將枚舉< - >字符串映射添加到默認映射。
+0

2018年看起來情況仍然如此。推土機項目似乎處於休眠狀態。我們在當前的項目中使用ModelMapper。 –