一种java对象转换成protobuf对象通用方法

protobuf的优势这里就不细说了,这里给java开发童鞋们分享一个可以将普通java对象转换成.proto生成的java对象的方法,大家在编写完.proto文件后生成java对象后,肯定都遇到过一个问题,就是不同的对象构造方法不一样,以下为本人写的一个通用方法:

   /**
     * 该方法将javabean对象转换成protobuf对应的bean
     * 
     * @param javaBean
     * @param protoBuilder
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Object javaBeanToProtoBean(Object javaBean, Object protoBuilder) {


        try {
            Method mm = protoBuilder.getClass().getMethod("getDescriptorForType");


            Descriptors.Descriptor descriptor = (Descriptor) mm.invoke(protoBuilder);


            Field[] fields = javaBean.getClass().getDeclaredFields();


            for (Field item : fields) {
                try{
                String fName = item.getName();
                item.setAccessible(true);
                Object jObject = item.get(javaBean);
                if(null == jObject){
                   break;
                }
                FieldDescriptor fd = descriptor.findFieldByName(fName);
                if(null != fd){
                    if(fd.isRepeated()){
                        boolean isDefined = false;
                            Method[] mmm = protoBuilder.getClass().getMethods();
                            for(Method mItem : mmm){
                                
                                try{
                                    String mName = mItem.getName();
                                    String mName1 = "add" + StringUtil.firstToUpperCase(fName);
                                    if(mName1.equals(mName) && mItem.getParameterTypes().length == 1){
                                        Class[] ccList = mItem.getParameterTypes();
                                        Class cc = ccList[0];
                                        Method me = cc.getMethod("newBuilder");
                                        Object oBuilder = me.invoke(null);//获取自定义对象builder
                                        
                                        List<Object> dList = (List<Object>) jObject; //数据为List集合
                                        List<Object> pBeanList = new ArrayList<Object>();
                                       for(Object oItem : dList){
                                          Object pBean = javaBeanToProtoBean(oItem,oBuilder);
                                          pBeanList.add(pBean);
                                       }
                                       Method mee = protoBuilder.getClass().getMethod("addAll"+StringUtil.firstToUpperCase(fName),Iterable.class);
                                       mee.invoke(protoBuilder, pBeanList); 
                                        isDefined = true;
                                    }   
                                }catch(Exception e){
                                    
                                }
                            
                            }    
                     
                      if(!isDefined){
                        try{
                            Method me = protoBuilder.getClass().getMethod("addAll"+StringUtil.firstToUpperCase(fName),Iterable.class);
                            me.invoke(protoBuilder, jObject);
                        }catch(Exception e){
                            LOG.info("this repeated field is a user-defined field");
                            e.printStackTrace();
                        }
                        } 


                    }else{
                        boolean isDefined1 = false;
                        try{
                            //自定义对象继续需要通过builder来解析处理,回调
                            Method bM = protoBuilder.getClass().getMethod("getFieldBuilder", FieldDescriptor.class);
                            Object subBuilder = bM.invoke(protoBuilder, fd);
                            Object pBean = javaBeanToProtoBean(jObject,subBuilder); 
                            Method me = protoBuilder.getClass().getMethod("setField", FieldDescriptor.class, Object.class);
                            me.invoke(protoBuilder, fd, pBean);
                            isDefined1 = true;
                        }catch(Exception e){
                            LOG.info("this required field is not a user-defined field");
                        }
                        
                        if(!isDefined1){
                            Method me = protoBuilder.getClass().getMethod("setField", FieldDescriptor.class, Object.class);
                            me.invoke(protoBuilder, fd, jObject);
                        }
                        
                    }
                }
                }catch(Exception e){
                    LOG.error("javaBeanToProtoBean method  item reflect error, item name:"+item.getName());
                }
            }
            
            Method buildM = protoBuilder.getClass().getMethod("build");
            Object rObject =  buildM.invoke(protoBuilder);
        /*    Method byteM = rObject.getClass().getMethod("toByteArray");
            Object byteObject =  byteM.invoke(rObject);
            byte[] pbByte = (byte[]) byteObject;  
            String pbStr = new String(Base64.getEncoder().encode(pbByte), "UTF-8");*/
            return rObject;
        } catch (Exception e) {
            e.printStackTrace();
            LOG.error("convert javabean to protobuf bean error,e:", e);
            return null;
        }

    }


此方法入参和返回结果都是Object类型,可以适用不同类型java对象  ,

 public static Object javaBeanToProtoBean(Object javaBean, Object protoBuilder) 

javaBean是已知普通java对象,protoBuilder是proto对象生成的builder 返回结果就是protoBuilder.build()出来的对象

注:编写的proto文件格式与javaBean对象要严格一一对应(参数名称和结构)

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Java中将对象转换Protobuf中定义的Any类型,你可以按照以下步骤进行操作: 1. 首先,你需要确保你的Java项目已经添加了Protobuf的依赖。你可以在Maven或Gradle的构建文件中添加以下内容: Maven: ```xml <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.18.1</version> </dependency> ``` Gradle: ```groovy implementation 'com.google.protobuf:protobuf-java:3.18.1' ``` 2. 确保你已经定义了Protobuf的消息和Any类型。假设你已经有一个定义了Any类型的.proto文件,并且生成了Java类。 3. 创建你要转换为Any类型的Java对象。 4. 使用Protobuf提供的Any.newBuilder()方法创建一个新的Any.Builder对象。 5. 使用Message.pack()方法Java对象打包为Any类型。 下面是一个示例代码: ```java import com.google.protobuf.Any; import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; // 假设你的Protobuf消息定义文件中包含了Any类型的定义 import your.protobuf.package.YourMessage; public class ObjectToAnyConverter { public static void main(String[] args) throws Exception { // 创建一个要转换为Any类型的Java对象 YourMessage.YourObject yourObject = YourMessage.YourObject.newBuilder() .setField1("Value 1") .setField2("Value 2") .build(); // 创建一个新的Any.Builder对象 Any.Builder anyBuilder = Any.newBuilder(); // 使用Message.pack()方法Java对象打包为Any类型 anyBuilder.pack(yourObject); // 获取转换后的Any对象 Any any = anyBuilder.build(); // 可选:将Any对象转换为JSON格式进行输出 String json = JsonFormat.printer().print(any); System.out.println(json); } } ``` 确保将`your.protobuf.package`替换为你自己的Protobuf包路径,并将`YourMessage`和`YourObject`替换为你自己的消息和对象名称。 这样,你就可以将Java对象转换Protobuf中定义的Any类型了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值