一种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对象要严格一一对应(参数名称和结构)
/**
* 该方法将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-net中的bcl.DateTime对象
- java对世界各个时区(TimeZone)的通用转换处理方法
- commerce中的把Java对象转换为JavaScript的对象的方法
- java/jsp乱码的一种转换方法
- java对世界各个时区(TimeZone)的通用转换处理方法
- 将Fri May 04 17:25:34 CST 2012形式的日期字符串转换成java.util.Date对象的方法
- JAVA中实现图片对象转换成图片文件和字节数组(Byte[ ])的方法讨论
- Effective Java 3:对于所有对象都通用的方法
- java 对象深拷贝通用方法
- Simple-Spring-Memcached使用Protobuf序列化Java对象
- Json字符串转换为java对象的各种实现方法【json_lib框架、Gson、org.json】
- Java中常用的一种时间格式的转换方法
- Json字符串转换为java对象的各种实现方法【json_lib框架、Gson、org.json】
- java 对象深拷贝通用方法
- java第七周实验封装一类对象English,该类对象具有一种功能printEnglish输出英文字母表。再封装一类对象Greek,该类必须是English的子类,该类对象不仅可以调用方法printE
- java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二)
- java对世界各个时区(TimeZone)的通用转换处理方法
- Java高效编程之二【对所有对象都通用的方法】
- java对象通用方法之覆盖equals时请遵守通用约定、覆盖equals时总要覆盖hashCode、始终要覆盖toString、考虑实现Comparable接口
- java中List对象排序的通用方法