grpc-java 常用.proto类型Java代码 demo

grpc-java 常用的.proto类型 demo 整理

博主近期在调研 istio,其中涉及需要将自己部门的 rpc 框架切换到 grpc-java 上,因此对 grpc-java 进行了相关调研,这里就对常用的.proto类型进行整理。

.proto文件中消息结构里用于定义字段的标准数据类型如下表所示,后面几列是.proto文件中定义的标准类型编译转换后在编程语言中的类型对照。
在这里插入图片描述
下面将对上面提到的 .proto 类型在 Java 代码中的使用给出代码示例
(下面的项目将在上一个示例:grpc-java springboot 同步异步调用 demo 的基础上进一步扩展)

主要包含的复杂结构:数组Mapbyte[]自定义结构枚举类型

首先是 .proto 文件:

syntax = "proto3"; //指定正在使用proto3语法,没有则默认为proto2

option java_package = "grpc.springboot.demo.api";
option java_outer_classname = "ComplexStructService";

package complex.struct.service;

service ComplexStruct {
    //定义一个rpc方法,请求跟相应的内容,均为自定义类型
    rpc invoker (ComplexStructRequest) returns (ComplexStructResponse) {}
}

//定义请求体
message ComplexStructRequest {
    //定义字符串类型
    string msg = 1;
    //定义浮点类型
    double num = 2;
    //定义long类型
    sint64 longNum = 3;
    //定义int类型
    sint32 shortNum = 4;
    //定义boolean类型
    bool check = 5;
    //定义int型数组
    repeated sint32 shortNumArray = 6;
    //定义字符串数组
    repeated string messageArray = 7;
    //定义map结构,k-v均为字符串
    map<string, string> testMap = 8;
    //定义枚举类型
    enumType enumTypeNum = 9;
    //定义字节数组
    bytes data = 10;
}

//定义响应类型
message ComplexStructResponse {
    //包含了自定义Result
    Result result = 1;
    //自定义Result的数组
    repeated Result resultList = 2;
    //自定义Result的map
    map<string, Result> resultMap = 3;
}

message Result {
    sint64 id = 1;
    string message = 2;
}

//枚举类型
enum enumType {
    ENUM_TYPE_0 = 0;
    ENUM_TYPE_1 = 1;
    ENUM_TYPE_2 = 2;
    ENUM_TYPE_3 = 3;
}

对于 List 或者是 Map,代码添加时,都可以通过 addAllXxxx 整个 List/Map 对象赋值,或者通过 addXxx 的方法,依次进行赋值。具体见客户端与服务端代码。

客户端代码:

@RestController
public class ComplexStructController {

    private static final Logger logger = LoggerFactory.getLogger(ComplexStructController.class);

    private GrpcClient client;

    @Autowired
    public ComplexStructController(GrpcClient client) {
        this.client = client;
    }

	// 这里构建了一个请求,用于触发客户端调用服务端
    @GetMapping("/complex/struct/hello")
    public String hello() {
        List<String> allMessageArray = new ArrayList<>();
        allMessageArray.add("string1");
        allMessageArray.add("string2");
        allMessageArray.add("string3");

        Map<String, String> testMap = new HashMap<>();
        testMap.put("key1", "value1");
        testMap.put("key2", "value2");

        String string = "hello world";
        byte[] bytes = string.getBytes();

        ComplexStructService.ComplexStructRequest request = ComplexStructService.ComplexStructRequest
                .newBuilder()
                // 添加基础的数据类型
                .setMsg("msg")
                .setNum(12.5)
                .setLongNum(12L)
                .setShortNum(10)
                .setCheck(true)
                .addShortNumArray(100)
                .addShortNumArray(200)
                .addShortNumArray(300)
                // 添加字符串数组对象
                .addAllMessageArray(allMessageArray)
                // 添加 map 对象
                .putAllTestMap(testMap)
                // 在已添加的 map 对象基础上,再添加元素
                .putTestMap("key3", "value3")
                .setEnumTypeNum(ComplexStructService.enumType.ENUM_TYPE_3)
                // 不能直接将byte[]类型放入,需要通过protobuf的ByteString进行一次转换
                .setData(ByteString.copyFrom(bytes))
                .build();
        logger.info("Build request:{}", request);

        try {
            // 获取同步存根
            ComplexStructGrpc.ComplexStructBlockingStub stub = client.getComplexStructBlockingStub();
            ComplexStructService.ComplexStructResponse response = stub.invoker(request);
            logger.info("Get response:{}", response);
            return "success";
        } catch (StatusRuntimeException e) {
            logger.info(" Error Received - Error code : {}", e.getStatus().getCode());
        }
        return "error";
    }
}

服务端代码:

@Component
public class ComplexStructServiceImpl extends ComplexStructGrpc.ComplexStructImplBase {

    private static final Logger logger = LoggerFactory.getLogger(ComplexStructServiceImpl.class);

    @Override
    public void invoker(ComplexStructService.ComplexStructRequest request,
                        StreamObserver<ComplexStructService.ComplexStructResponse> responseObserver) {
        logger.info("receive request:{}", request);
        // 对于基础的数据类型,直接通过 getXxx() 获取
        String msg = request.getMsg();
        double num = request.getNum();
        long longNum = request.getLongNum();
        int shortNum = request.getShortNum();
        boolean check = request.getCheck();
        logger.info("msg:{}, num:{}, longNum:{}, shortNum:{}, check:{}", msg, num, longNum, shortNum, check);

        // 对于数组,可以获取完整的 List 对象,也可以获取数组对象的长度,再通过下标获取特定的对象
        List<Integer> shortNumList = request.getShortNumArrayList();
        int shortNumListNum = request.getShortNumArrayCount();
        int shortNumListFirstNum = request.getShortNumArray(0);
        logger.info("shortNumListNum:{}, shortNumListFirstNum:{}, shortNumList[1]:{}",
                shortNumListNum, shortNumListFirstNum, shortNumList.get(1)) ;

        // 字符串数组同上
        List<String> messageArray = request.getMessageArrayList();
        int messageArrayNum = request.getMessageArrayCount();
        String messageArrayFirstMsg =request.getMessageArray(0);
        logger.info("messageArrayNum:{}, messageArrayFirstMsg:{}, messageArray[1]:{}",
                messageArrayNum, messageArrayFirstMsg, messageArray.get(1)) ;

        // 对于 map 类型,也可以直接获取到完整的对象
        Map<String, String> testMap = request.getTestMapMap();
        for (String key : testMap.keySet()) {
            logger.info("testMap: key:{}, value:{}", key, testMap.get(key));
        }

        // 获取枚举类型 或 直接获取枚举类型的值
        ComplexStructService.enumType enumType = request.getEnumTypeNum();
        int enumTypeValue = request.getEnumTypeNumValue();
        logger.info("enumType:{}, enumTypeValue:{}", enumType, enumTypeValue);

		// 获取字节数组
        byte[] bytes = request.getData().toByteArray();
        logger.info("data:{}", new String(bytes));

        // 构建响应类
        ComplexStructService.Result result = buildResult(100L, "single result");

        // 构建响应数组
        List<ComplexStructService.Result> resultList = new ArrayList<>();
        resultList.add(buildResult(1L, "result list 1"));
        resultList.add(buildResult(2L, "result list 2"));

        // 构建响应 Map 结构
        Map<String, ComplexStructService.Result> resultMap = new HashMap<>();
        resultMap.put("resultMap-key1", buildResult(1L, "result map 1"));
        resultMap.put("resultMap-key2", buildResult(2L, "result map 2"));

        ComplexStructService.ComplexStructResponse response =
                ComplexStructService.ComplexStructResponse
                        .newBuilder()
                        .setResult(result)
                        // 加入定义的 Result 数组
                        .addAllResultList(resultList)
                        // 在 Result 数组上再加入新的 Result 对象
                        .addResultList(buildResult(3L, "result list 3"))
                        // 加入定义的 Map 对象
                        .putAllResultMap(resultMap)
                        // 在 Map 对象上再加入新的元素
                        .putResultMap("resultMap-key3", buildResult(3L, "result map 3"))
                        .build();
        logger.info("return response:{}", response);
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }

    private ComplexStructService.Result buildResult(long id, String msg) {
        return ComplexStructService.Result
                .newBuilder()
                .setId(id)
                .setMessage(msg)
                .build();
    }
}

运行结果:

服务端:

2021-04-01 00:46:29.870  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : receive request:msg: "msg"
num: 12.5
longNum: 12
shortNum: 10
check: true
shortNumArray: 100
shortNumArray: 200
shortNumArray: 300
messageArray: "string1"
messageArray: "string2"
messageArray: "string3"
testMap {
  key: "key1"
  value: "value1"
}
testMap {
  key: "key2"
  value: "value2"
}
testMap {
  key: "key3"
  value: "value3"
}
enumTypeNum: ENUM_TYPE_3
data: "hello world"

2021-04-01 00:46:29.879  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : msg:msg, num:12.5, longNum:12, shortNum:10, check:true
2021-04-01 00:46:29.880  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : shortNumListNum:3, shortNumListFirstNum:100, shortNumList[1]:200
2021-04-01 00:46:29.880  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : messageArrayNum:3, messageArrayFirstMsg:string1, messageArray[1]:string2
2021-04-01 00:46:29.880  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : testMap: key:key1, value:value1
2021-04-01 00:46:29.880  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : testMap: key:key2, value:value2
2021-04-01 00:46:29.880  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : testMap: key:key3, value:value3
2021-04-01 00:46:29.880  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : enumType:ENUM_TYPE_3, enumTypeValue:3
2021-04-01 00:46:29.880  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : data:hello world
2021-04-01 00:46:29.883  INFO 6460 --- [ault-executor-0] c.p.g.d.s.s.ComplexStructServiceImpl     : return response:result {
  id: 100
  message: "single result"
}
resultList {
  id: 1
  message: "result list 1"
}
resultList {
  id: 2
  message: "result list 2"
}
resultList {
  id: 3
  message: "result list 3"
}
resultMap {
  key: "resultMap-key1"
  value {
    id: 1
    message: "result map 1"
  }
}
resultMap {
  key: "resultMap-key2"
  value {
    id: 2
    message: "result map 2"
  }
}
resultMap {
  key: "resultMap-key3"
  value {
    id: 3
    message: "result map 3"
  }
}

客户端运行结果:

2021-04-01 00:46:28.666  INFO 4616 --- [io-10088-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2021-04-01 00:46:28.667  INFO 4616 --- [io-10088-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2021-04-01 00:46:28.684  INFO 4616 --- [io-10088-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 17 ms
2021-04-01 00:46:28.743  INFO 4616 --- [io-10088-exec-1] c.p.g.d.c.c.ComplexStructController      : Build request:msg: "msg"
num: 12.5
longNum: 12
shortNum: 10
check: true
shortNumArray: 100
shortNumArray: 200
shortNumArray: 300
messageArray: "string1"
messageArray: "string2"
messageArray: "string3"
testMap {
  key: "key1"
  value: "value1"
}
testMap {
  key: "key2"
  value: "value2"
}
testMap {
  key: "key3"
  value: "value3"
}
enumTypeNum: ENUM_TYPE_3
data: "hello world"

2021-04-01 00:46:29.911  INFO 4616 --- [io-10088-exec-1] c.p.g.d.c.c.ComplexStructController      : Get response:result {
  id: 100
  message: "single result"
}
resultList {
  id: 1
  message: "result list 1"
}
resultList {
  id: 2
  message: "result list 2"
}
resultList {
  id: 3
  message: "result list 3"
}
resultMap {
  key: "resultMap-key1"
  value {
    id: 1
    message: "result map 1"
  }
}
resultMap {
  key: "resultMap-key2"
  value {
    id: 2
    message: "result map 2"
  }
}
resultMap {
  key: "resultMap-key3"
  value {
    id: 3
    message: "result map 3"
  }
}

完整的代码连接:https://github.com/Parallelline1996/Daily-Learning/tree/master/gRPC/code-repository/grpc-springboot-demo

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值