君小黑 2019-09-08
分布式开发涉及到远程过程调用即RPC。需要集成grpc。但如果想无缝集成,则涉及到普通的请求对象转换为grpc请求对象。
由于null不能序列化,所以grpc的对象属性都会有默认值,这在开发中,很难区分,到底请求传的是默认值还是请求本身携带的值。所以使用protocol buffers 的oneof关键字,用于规避默认值。
新建员工类
package com.dld.hll.financial; import java.math.BigDecimal; import java.sql.Date; import java.sql.Timestamp; import java.util.List; import java.util.Map; import java.util.Set; /** * @Author yue chao * @Date 2019/8/10 0010 下午 21:23 */ public class EmpOne { private Long empIdOne; private String empNameOne; private Boolean empSexOne; private Long totalAssetOne; private List<String> skills; private Set<Integer> lucks; private Map<String, String> relations; private Date bornDate; private Timestamp createTime; private BigDecimal salary; private DeptOne dept; // ... 省略 get set }
新建部门类
package com.dld.hll.financial; /** * @Author yue chao * @Date 2019/8/10 0010 下午 21:24 */ public class DeptOne { private Long deptIdOne; private String deptNameOne; private Byte deptTypeOne; // 省略 get set }
proto文件
syntax = "proto3"; option java_multiple_files = true; option java_package = "com.dld.hll.financial.grpc"; option java_outer_classname = "EmpProto"; message EmpOne { oneof oneof_empId { int64 empIdOne = 4; } oneof oneof_totalAssetOne { int64 totalAssetOne = 8; } oneof oneof_empName { string empNameOne = 5; } oneof oneof_empSex { bool empSexOne = 6; } DeptOne dept = 7; repeated string skills = 9; repeated int32 lucks = 10; map<string, string> relations = 11; oneof oneof_bornDate { string bornDate = 12; } oneof oneof_createTime { string createTime = 13; } oneof oneof_salary { string salary = 14; } } message DeptOne { oneof oneof_deptId { int32 deptIdOne = 4; } oneof oneof_deptName { string deptNameOne = 5; } oneof oneof_deptType { int32 deptTypeOne = 6; } }
单元测试代码
package com.dld.hll.financial; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.protobuf.util.JsonFormat; import org.apache.commons.lang3.StringUtils; import org.junit.Test; import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * @Author yue chao * @Date 2019/8/12 0012 上午 11:40 */ public class EmpOneTest { /** * oneof 普通请求转grpc请求,再转普通请求 * @throws IOException */ @Test public void testOneCommonRequestTransformToGrpcRequest() throws IOException { oneCommonRequestTransformToGrpcRequest(); } public static void oneCommonRequestTransformToGrpcRequest() throws IOException { DeptOne dept = new DeptOne(); dept.setDeptIdOne(0L); dept.setDeptNameOne(StringUtils.EMPTY); dept.setDeptTypeOne((byte)0); List<String> skills = new ArrayList<>(); skills.add("EDVSD"); Set<Integer> lucks = new HashSet<>(); EmpOne emp = new EmpOne(); emp.setEmpIdOne(0L); emp.setEmpNameOne(StringUtils.EMPTY); emp.setEmpSexOne(false); emp.setDept(dept); emp.setSkills(skills); emp.setLucks(lucks); emp.setBornDate(new java.sql.Date(System.currentTimeMillis())); emp.setCreateTime(new java.sql.Timestamp(System.currentTimeMillis())); emp.setSalary(new BigDecimal("22.33")); Gson gson = new GsonBuilder().serializeNulls() .setPrettyPrinting() .registerTypeAdapter(java.sql.Timestamp.class, new TimeStampGSON()) .registerTypeAdapter(java.sql.Date.class, new SqlDateGSON()) .create(); String empJson = gson.toJson(emp); System.out.println("普通对象json=============="); System.out.println(empJson); com.dld.hll.financial.grpc.EmpOne.Builder builder = com.dld.hll.financial.grpc.EmpOne.newBuilder(); JsonFormat.parser().merge(empJson, builder); com.dld.hll.financial.grpc.EmpOne empOneGrpc = builder.build(); StringBuilder sb = new StringBuilder(); JsonFormat.printer() .includingDefaultValueFields() // 设置采用默认值,当集合为空的时候会使用[]表示,map为空的时候采用{},这样可能有效防止直接使用而遇到的空指针 .appendTo(empOneGrpc, sb); System.out.println("grpc对象Json=============="); // 可以观察到普通对象json与grpcJson的区别,grpcJson对象字段为null的字段不显示,集合或map为空,则使用以上规则处理了 System.out.println(sb); Gson gson2 = new GsonBuilder() .setPrettyPrinting() .serializeNulls() .registerTypeAdapter(java.sql.Timestamp.class, new TimeStampGSON()) .registerTypeAdapter(java.sql.Date.class, new SqlDateGSON()) .create(); EmpOne vo = gson2.fromJson(sb.toString(), EmpOne.class); System.out.println("普通对象json=============="); System.out.println(gson2.toJson(vo)); } }
测试结果
普通对象json============== { "empIdOne": 0, "empNameOne": "", "empSexOne": false, "totalAssetOne": null, "skills": [ "EDVSD" ], "lucks": [], "relations": null, "bornDate": "2019-08-12", "createTime": "2019-08-12 13:39:14", "salary": 22.33, "dept": { "deptIdOne": 0, "deptNameOne": "", "deptTypeOne": 0 } } grpc对象Json============== { "empIdOne": "0", "empNameOne": "", "empSexOne": false, "dept": { "deptIdOne": 0, "deptNameOne": "", "deptTypeOne": 0 }, "skills": ["EDVSD"], "lucks": [], "relations": { }, "bornDate": "2019-08-12", "createTime": "2019-08-12 13:39:14", "salary": "22.33" } 普通对象json============== { "empIdOne": 0, "empNameOne": "", "empSexOne": false, "totalAssetOne": null, "skills": [ "EDVSD" ], "lucks": [], "relations": {}, "bornDate": "2019-08-12", "createTime": "2019-08-12 13:39:14", "salary": 22.33, "dept": { "deptIdOne": 0, "deptNameOne": "", "deptTypeOne": 0 } }