2017-05-05 3 views
0

Ich möchte kopieren Sie einige Felder von einem Java-Objekt zu anderen Java-Objekt dynamisch. Klassen dieser Objekte sind unterschiedlich.Kopieren Sie dynamisch primitive sowie komplexe Objekttyp-Felder in Java mit automatischer Konvertierung

unten ist das Szenario

  1. ich mit einigen Feldern einige Ressourcenklassen haben. Es gibt wenige Felder in jeder Klasse, die vom Benutzer geändert werden können, aber diese Felder sind nicht in allen Ressourcenklassen identisch. Die Liste der modifizierbaren Felder für jede Klasse wird in einigen Datenstrukturen gepflegt.

  2. Die meisten Felder sind ähnlich und einige sind konvertierbar wie man primitive und andere Wrapper-Klasse hat. Einige Felder sollten von Nummerntypen in String oder umgekehrt werden.

  3. Die meisten Felder sind komplexe Objekttypen.

Welche der verfügbaren Bibliotheken heute wird mir helfen, diese Felder mit automatischer Konvertierung Kopieren, wo immer und tiefe Kopie erforderlich? Früher war ich mit BeanUtils, aber das ist keine tiefe Kopie. Weder unterstützt es automatische Konvertierung.

Antwort

0

Ich dachte, Frühling Rahmen könnte help.Here meines Beispiel des Frühlings-core-4.1.5:

Klassendeklaration:

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

main-Methode:

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

Ergebnisse:

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

+0

Das scheint feine Lösung, aber ich habe ein paar Fragen. Warum muss ich Konverter deklarieren, sollte automatisch die Quell- und Zielklasse automatisch finden. – SacJn

+0

Und ich benutze Struts Framework bereits so Kann es einige Konflikte verursachen, wenn ich diese Bibliothek verwende? Ein weiteres Problem, das ich jetzt finde. Quell- und Konverterklassen haben für einige Felder nicht den gleichen Namen. – SacJn