规范化Java bean属性名称

时间:2012-06-19 09:02:52

标签: java javabeans

我有一堆第三方Java类,它们使用不同的属性名称来构建基本相同的属性:

public class Foo {
   public String getReferenceID();
   public void setReferenceID(String id);
   public String getFilename();
   public void setFilename(String fileName);
}

public class Bar {
   public String getRefID();
   public void setRefID(String id);
   public String getFileName();
   public void setFileName(String fileName);
}

我希望能够以规范化的形式解决这些问题,以便我可以多态地对待它们,以便我可以使用Apache BeanUtils来完成这些工作:

PropertyUtils.copyProperties(object1,object2);

显然,为每个类写一个适配器是微不足道的......

public class CanonicalizedBar implements CanonicalizedBazBean {
    public String getReferenceID() {
        return this.delegate.getRefID();
    }
    // etc.
}

但是我想知道那里有更普遍和动态的东西吗?什么东西需要一对多的属性名称等价映射,以及委托类,并生成适配器?

5 个答案:

答案 0 :(得分:6)

我从未使用它,但我认为你正在寻找Dozer

  

Dozer是Java Bean to Java Bean映射器,它以递归方式复制数据   从一个对象到另一个对象。通常,这些Java Bean将是   不同的复杂类型。

     

Dozer支持简单属性映射,复杂类型映射,   双向映射,隐式显式映射,以及   递归映射。这包括映射集合属性   还需要在元素级别进行映射。

     

Dozer不仅支持属性名称之间的映射,还支持   自动在类型之间转换。大多数转换方案都是   支持开箱即用,但Dozer也允许您指定自定义   通过XML进行转换。

答案 1 :(得分:4)

  1. 第一个选项是Dozer

  2. 第二个选项是Smooks框架 调整。使用Smook的图形映射器将是有益的。

  3. 使用自定义Mapper的另一个选项是XStream

答案 2 :(得分:2)

也许是这样的:

public class CanonicalizedBar implements CanonicalizedBazBean {
public String getReferenceID() {
    Method m = this.delegate.getClass().getDeclaredMethod("getReferenceID");
    if(m == null)
        m = this.delegate.getClass().getDeclaredMethod("getRefID");
    ...
    return m.invoke();
}
// etc.
}

答案 3 :(得分:2)

虽然,我个人从未使用过它。我注意到一个名为orika的项目被认为具有最佳性能和自动理解许多此类映射的能力。 无论如何,它还支持自定义映射,并使用生成的代码隐式定义适配器。

您还可以定义自定义映射器,即如果您知道如何对成员名称进行规范化,则可以使用该知识来构建对所有对象都适用的映射。例如:

DefaultFieldMapper myDefaultMapper = new DefaultFieldMapper() {
   public String suggestMapping(String propertyName, Type<?> fromPropertyType) {
      // split word according to camel case (apache commons lang)
      String[] words= StringUtils.splitByCharacterTypeCamelCase(propertyName);
      if(words[0].length() > 6) {
         // trim first camel-cased word of propery name to 3 letters
         words[0]= words[0].substring(0,2);
         return StringUtils.join(words);
      } else {
         // remains unchanged
         return propertyName;
      }   
   }
}

mapperFactory.registerDefaultFieldMapper(myDefaultMapper );

答案 4 :(得分:1)

我没有做太多,但您可以使用Aspect Oriented Programming来做到这一点。

你应该能做什么我认为是为每个内部调用真实方法的类添加一个方法。请参阅此article,大约有一半是关于mixins的。

AspectJ可能是最受欢迎的实现。