2017-05-05 9 views
0

일부 필드을 하나의 Java 객체에서 다른 Java 객체로 동적으로 복사하려고합니다. 이 개체의 클래스는입니다.Java에서 자동 변환을 사용하여 원시 및 복합 객체 유형 필드를 동적으로 복사합니다.

다음은 시나리오 일부 필드 일부 자원 수업을

  1. 입니다. 사용자가 수정할 수있는 각 클래스에 필드가 몇 개 있지만이 필드 은 모든 리소스 클래스에서 동일하지 않은 입니다. 각 클래스에 대한 수정 가능한 필드 목록 이 일부 데이터 구조에서 유지 관리됩니다.

  2. 필드의 대부분은 비슷하며 하나는 프리미티브가 있고 다른 하나는 래퍼 클래스가있는 것처럼 변환 가능합니다. 일부 필드는 이 Number 유형에서 String으로 또는 그 반대로 변환되어야합니다.

  3. 대부분의 필드는 복잡한 개체 유형입니다.

가능한 라이브러리의 어느 오늘이 지금 필요한 자동 변환을 필드와 깊은 사본을 복사 나에게 도움이 될 것입니다? 이전에 내가 사용하고 있었다 BeanUtils 그러나 이것은 깊은 사본이 아니다. 어느 쪽도 자동 변환을 지원하지 않습니다.

답변

0

나는 생각 스프링 프레임 워크 수도 스프링 코어-4.1.5의 help.Here의 내 예 :

클래스 선언 :

public static class A{ 
    private String a; 
    private String b; 
    private String c; 
    private C d; 
    private int e; 
//getter&setter here 

public static class C { 
    private String aa; 
    private String bb; 
    private String cc; 

    //getter&setter here 

public static class B{ 
    private Integer a; 
    private Long b; 
    private Boolean c; 
    private D d; 
    private Integer e; 

    //getter&setter here 

public static class D { 
    private Integer aa; 
    private Long bb; 
    private Boolean cc; 

    //getter&setter here 

class ObjectConverter implements Converter<Object, Object> { 
    private final ConversionService conversionService; 
    private final Class targetClass; 

    public ObjectConverter(ConversionService conversionService, Class targetClass) { 
     this.conversionService = conversionService; 
     this.targetClass = targetClass; 
    } 

    @Override 
    public Object convert(Object source) { 
     Object ret=null; 
     try { 
      ret = targetClass.newInstance(); 

      Field[] fields = targetClass.getDeclaredFields(); 
      for (Field field : fields) { 
       PropertyDescriptor sourceDescriptor = new PropertyDescriptor(field.getName(),source.getClass()); 
       PropertyDescriptor targetDescriptor = new PropertyDescriptor(field.getName(),targetClass); 

       if (sourceDescriptor.getReadMethod()==null || targetDescriptor.getWriteMethod() == null) { 
        //record error here 
        break; 
       } 

       Class<?> sourcePType = sourceDescriptor.getPropertyType(); 
       Class<?> targetPType = targetDescriptor.getPropertyType(); 
       if(conversionService.canConvert(sourcePType,targetPType)){ 
        Object sourceValue = sourceDescriptor.getReadMethod().invoke(source); 
        Object targetValue = conversionService.convert(sourceValue, targetPType); 
        targetDescriptor.getWriteMethod().invoke(ret,targetValue); 
       } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return ret; 
    } 
} 

주요 방법 :

A orgA = new A(); 
    orgA.a="123"; 
    orgA.b="1234567"; 
    orgA.c="1"; 
    orgA.d = new C(); 
    orgA.d.aa="321"; 
    orgA.d.bb="7654321"; 
    orgA.d.cc="0"; 
    orgA.e=-99; 

    System.out.println(orgA); 

    try { 
     ConfigurableConversionService conversionService = new DefaultConversionService(); 

     //if you are not satisfied with the final A result, then 
     //customize your own Boolean->String Converter; 
//   conversionService.addConverter(new Converter<Boolean, String>() { 
//    @Override 
//    public String convert(Boolean source) { 
//     return source==null||!source?"0":"1"; 
//    } 
//   }); 

     conversionService.addConverter(A.class, B.class, new ObjectConverter(conversionService, B.class)); 
     conversionService.addConverter(B.class, A.class, new ObjectConverter(conversionService, A.class)); 

     conversionService.addConverter(C.class, D.class, new ObjectConverter(conversionService, D.class)); 
     conversionService.addConverter(D.class, C.class, new ObjectConverter(conversionService, C.class)); 

     B b = conversionService.convert(orgA, B.class); 
     System.out.println(b); 

     A a = conversionService.convert(b, A.class); 
     System.out.println(a); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

검색 결과 :

A {a = '123', b = '1234567', c = '1', d = C {aa = '321', bb = '7654321', cc = '0'}, e =
B {a = 123, b = 1234567, c = true, d = D {aa = 321, bb = 7654321, cc = false}, e = -99}
A {a = '123', b = '1234567', c = 'true', d = C {aa = '321', bb = '7654321', cc = 'false'}, e = -99}

+0

이것은 좋은 해결책 인 것 같습니다. 변환기를 선언해야하는 이유는 자동으로 소스 및 대상 클래스를 자동으로 찾아야합니다. – SacJn

+0

그리고 struts 프레임 워크를 이미 사용하고 있습니다.이 라이브러리를 사용하면 충돌이 발생할 수 있습니다. 한 가지 더 문제가 있습니다. 원본 및 변환기 클래스는 일부 필드의 이름이 같지 않습니다. – SacJn