2011-11-25 24 views
15

Tôi có enum như:Dozer String để enum mapping

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; 
    } 
} 

tôi cần phải chuyển nó sang String và ngược lại. Bây giờ, nó được thực hiện bằng công cụ chuyển đổi tùy chỉnh. Nhưng tôi muốn làm điều đó thông qua ánh xạ dozer (nếu có thể). Nếu tôi không viết bất kỳ ánh xạ nào lên conf dozer, tôi sẽ nhận được

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

ngoại lệ. Tôi không thể thêm constructor công khai mặc định vào enum, vì nó là không thể. Vì vậy, tôi đã viết một thủ thuật với mã nội bộ và valueOfCode()/toString(). Nó không hoạt động. Sau đó, tôi đã ánh xạ nó trong cấu hình dozer:

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

Nó không hoạt động. Tôi đã thử valueOfCode(), ánh xạ một chiều. Không có gì hiệu quả. Enum để chuyển đổi chuỗi không hoạt động quá, tôi nhận được chuỗi rỗng. Bất kỳ ý tưởng nào?

+1

Tôi đã thêm công cụ chuyển đổi tùy chỉnh của mình vào máy chủ dozer. Vì vậy, không ai từ 5.4 sẽ không phải đối mặt với vấn đề này :) – madhead

+0

@all Bất cứ ai có thể nhìn vào [Câu hỏi] này (http://stackoverflow.com/questions/27864640/dozer-string-to-date-field-level-mapping-for -a-list) – 09Q71AO534

Trả lời

19

Không chắc chắn nếu điều này vẫn còn là một vấn đề, nhưng có thể giúp đỡ cho bất cứ ai tìm kiếm. Nhưng đây là giải pháp được triển khai cho điều này:

@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; 
} 

Lớp StrBuilder khi xây dựng thông báo ngoại lệ là từ apache common-lang libs. Nhưng khác hơn là một sự phản ánh đơn giản để giải quyết vấn đề này. Chỉ cần thêm một lớp mà thực hiện CustomConverter và sau đó trong dozer tập tin xml lập bản đồ của bạn thêm cấu hình sau:

<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> 

Lưu ý rằng bạn chỉ có thể liệt kê một cấu hình một lần giữa tất cả các tập tin bản đồ của bạn (nếu bạn có nhiều) khác dozer sẽ phàn nàn. Những gì tôi thường làm là đặt cấu hình chuyển đổi tùy chỉnh của tôi trong một tệp để đơn giản. Hi vọng điêu nay co ich!

4

Không có enum mặc định để ánh xạ chuỗi trong Dozer. Xem Data type conversion từ tài liệu Dozer. Vì vậy, bạn có hai tùy chọn:

  • Bạn có thể viết công cụ chuyển đổi tùy chỉnh sử dụng Generics để xử lý bất kỳ enum nào.
  • Hoặc bạn có thể gửi bản vá cho Dozer để thêm enum < -> Ánh xạ chuỗi vào ánh xạ mặc định.
+0

Có vẻ như điều này vẫn đúng vào năm 2018. Dự án Dozer dường như không hoạt động. Chúng tôi sử dụng ModelMapper trong dự án hiện tại của chúng tôi. –