2011-11-25 102 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。 –