使用springboot写一个可以响应protobuffer的接口

写在前面

几经波折,最终进了一家公司实习,不过实习公司用的技术我都很陌生。但是的确,面试上没有要求这些技术。
办完了入职手续之后,就给我了个练习,给了我两个GitHub的链接,一个是protobuffer的,另一个是tars的,练习是:使用springboot写一个可以响应protobuffer的接口。

准备工作

因为都不知道protobuffer是什么东西,所以得先学习protobuffer。

protocol buffer是Google的一种独立的数据交换格式,可运用于多种领域。

protobuffer就是一种数据交换格式,和json、xml类似,但是比json、xml效率更加高,因为序列化之后更小,而且独立于语言、平台。缺点就是:编码后的数据可读性差。
protobuffer独立于语言和平台,需要protobuffer编译器的支持,所以需要安装protobuffer编译器。IDEA下有一个插件:GenProtobuf,这个插件可以自动的生成编译之后的Java类,不过也需要在Configure GenProtobuf中配置一下protobuf编译器。所以无论如何都需要安装protobuf的编译器,只不过在idea中安装了插件之后,不用再手动的去生成Java类了。
在这里插入图片描述

正式着手

mac本,使用IDEA工具,不过都其他系统、工具都大同小异。

第一步 创建工程

创建springboot工程,除了web模块之外,还需要引入protobuf的依赖

        <!--protobuf的依赖-->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.14.0</version>
        </dependency>
        <dependency>
            <groupId>com.googlecode.protobuf-java-format</groupId>
            <artifactId>protobuf-java-format</artifactId>
            <version>1.2</version>
        </dependency>

然后补全项目结构

第二步 protobuf的准备
2.1 首先编写protobuf文件

例如:

// 表示是proto3的语法,proto3不能使用"required"
syntax = "proto3";
// 表示生成的序列化器的Java包
option java_package = "com.protobuf.protobuf.protobuf";
// 表示生成的Java序列化器的类名
option java_outer_classname = "Serializer";
// 表示一个消息
message Teacher{
    // proto中的数据类型  字段名 = 唯一编号
    // 编号范围 1-536870911,19000,19999两个不能使用 1-15编号占用一个字节,16-2047占用两个字节,常用字段应该使用1-15
	 int64 teacherId = 1;
	 int32 age = 2;
	 string name = 3;
}   
2.2 使用插件生成Java类

例如:
在这里插入图片描述

第三步 编写接口
3.1 思路

这里是主要的实现逻辑,我的思路是:将一个实体序列化之后,再使用base64进行编码,编码成字符串,这个字符串就是我传输的对象。就像在json中,[1,2,3]表示一个数组一样。的确,protobuf编码之后的可读性很差,或者说根本没有可读性。在进行传输的时候,就将需要传输的内容放到请求体里,然后在接口中拿到这个字符串之后,先对字符串进行base64解码,然后再进行protobuf反序列化,将实例还原出来。需要响应protobuf格式的数据,那就先构造一个实例,然后使用protobuf进行序列化,在使用base64进行编码,将编码出来的字符串设置到响应体里。这样就完成了,请求和响应都使用了protobuf格式的数据。

3.2 代码
import com.ql.protobuftest.util.Serializer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Base64;

@RestController
@RequestMapping("/test")
public class ProtobufController {

    @RequestMapping("/test1")
    public String test1(HttpServletRequest request) {

        //获取请求体里的字符串
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        try {
            br = request.getReader();
            String str;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        String requestBody = sb.toString();

        byte[] decode = null;
        try {
            //使用base64解码读取到的字符串,
            decode = Base64.getDecoder().decode(requestBody);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Serializer.Teacher teacher;
        try {
            // 将解析出来的字符串进行反序列化
            teacher = Serializer.Teacher.parseFrom(decode);
        } catch (Exception e) {
            // 如果解析失败,就返回一个特殊的实例
            teacher = Serializer.Teacher.newBuilder().setName("-1").setTeacherId(-1).setAge(-1).build();
            e.printStackTrace();
        }
        // 查看是否反序列化成功
        System.err.println("teacher=" + teacher.toString());

        // 返回一个序列化并且经过base64编码的字符串
        Serializer.Teacher.Builder builder = Serializer.Teacher.newBuilder().setName("2").setAge(2).setTeacherId(2);
        return Base64.getEncoder().encodeToString(builder.build().toByteArray());
    }
}
第四步 测试

使用工具postman进行测试,对接口进行调用。
在这里插入图片描述

可以看到,请求体中携带了经过序列化并且使用base64编码的字符串,在接口中可以进行解析并且反序列化,将原本的对象还原回来。接口最后返回了一个将对象序列化之后并且经过base64编码的字符串。

ok 完成。我自己在写的时候,前面还写了好几个版本,但是都不太好,有问题。最终这版,我自己觉得还不错。

有什么不对或不懂的地方,欢迎讨论交流。
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以回答这个问题。以下是使用Spring Boot编点赞接口的示例代码: 首先,我们需要创建一个名为“LikeController”的Java类,它将处理点赞请求: ``` @RestController public class LikeController { @PostMapping("/like") public String like() { // 处理点赞请求的逻辑 return "点赞成功!"; } } ``` 在这个类中,我们使用了Spring Boot的@RestController注解,它表示这个类将处理HTTP请求,并返回响应。我们还使用了@PostMapping注解,它表示这个方法将处理HTTP POST请求。 在like()方法中,我们可以编处理点赞请求的逻辑。在这个示例中,我们只是简单地返回一个字符串,表示点赞成功。 接下来,我们需要在Spring Boot应用程序的入口类中添加一些配置,以启用Spring Boot的自动配置和Web支持: ``` @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 在这个类中,我们使用了@SpringBootApplication注解,它表示这个类是Spring Boot应用程序的入口点。我们还使用了SpringApplication类的run()方法来启动应用程序。 现在,我们已经完成了点赞接口的编。我们可以使用任何HTTP客户端来测试它,例如cURL或Postman。当我们向http://localhost:8080/like发送一个HTTP POST请求时,我们应该会收到一个“点赞成功!”的响应。 希望这个示例能够帮助你编自己的Spring Boot应用程序!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值