通常,我可以使用带有java反射的beanutils在两个具有相同属性名的java bean之间复制值,例如PropertyUtils.setProperty(...)
在protobuf消息中,我们使用消息构建器类来设置值。这是可行的,但我更愿意使用反射将属性从bean自动复制到消息中,因为两者具有相同的属性名称和类型。
当我在构建器对象(从message.newBuilder()获得)上调用PropertyUtils.setProperty时,我收到以下消息。
setter :在类的类teststuff.TestBeanProtos$TestBeanMessage$Builder‘中没有java.lang.NoSuchMethodException属性testProp
如何使用java反射自动将值从java bean复制到protobuf消息对象(反之亦然)?
发布于 2010-10-29 17:09:20
我讨厌回答我的问题,但我不敢相信我是唯一遇到这个问题的人。在这里记录解决方案,以防其他人也开始使用protobuf和java。使用反射可以省去编写大量的getter和setter函数。
好的,我设法让它工作,使用一些示例测试代码随protobuf一起发布。这是一个非常简单的用例;通常情况下,消息要复杂得多。此代码不处理嵌套消息或重复消息。
public static void setMessageBuilder(com.google.protobuf.GeneratedMessage.Builder message,Descriptors.Descriptor descriptor,Object srcObject) throws Exception {
String cname = srcObject.getClass().getName();
/*BeanMapper.getSimpleProperties -- this is a warpper method that gets the list of property names*/
List<String> simpleProps = BeanMapper.getSimpleProperties(srcObject.getClass());
Map map = new HashMap();
for (String pName : simpleProps) {
System.out.println(" processing property "+ pName);
Object value= PropertyUtils.getProperty(srcObject, pName);
if(value==null) continue;
Descriptors.FieldDescriptor fd=descriptor.findFieldByName(pName) ;
System.out.println(" property "+ pName+" , found fd :"+ (fd==null ? "nul":"ok"));
message.setField(fd, value);
System.out.println(" property "+ pName+" set ok,");
}
return ;
}
发布于 2010-10-29 18:00:26
我可能要走了,但是protostuff能帮上忙吗?它很好地扩展了对其他数据格式、类型的支持。即使它没有直接转换支持,如果您转到JSON或从JSON转到JSON,对于良好的数据绑定也有许多选择。
发布于 2010-10-29 18:27:45
我不知道您的项目有多大,但您可能想试试Dozer,这是一种映射器,可以将数据从一个对象递归复制到同一类型的另一个对象,或者在不同的复杂类型之间复制数据。也支持隐式和显式映射。我在一个大项目中使用了它,并且工作得很好。它可以像这样简单
Mapper mapper = new DozerBeanMapper();
DestinationObject destObject = mapper.map(sourceObject, DestinationObject.class);
https://stackoverflow.com/questions/4053691
复制