您的位置:首页 > 编程语言 > Java开发

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

2017-11-30 09:25 711 查看
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
4000
文件格式与javaBean对象要严格一一对应(参数名称和结构)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java protobuf 对象转换
相关文章推荐