集成grpc普通对象与grpc对象转换

41次阅读

共计 4638 个字符,预计需要花费 12 分钟才能阅读完成。

集成 grpc,普通对象与 grpc 对象转换

分布式开发涉及到远程过程调用即 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
  }
}

正文完
 0