基于http的protobuf服务实现
本文介绍在http协议中,使用protobuf格式进行二进制数据通信。双方需设置http的header中ContentType为application/x-protobuf。
1、springboot下实现protobuf:
1)pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- protobuf -->
<dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.11.0</version>
</dependency>
<dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java-util</artifactId><version>3.11.0</version>
</dependency>
<dependency><groupId>com.googlecode.protobuf-java-format</groupId><artifactId>protobuf-java-format</artifactId><version>1.2</version>
</dependency>
<!-- 网络请求依赖 -->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version>
</dependency>
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4</version>
</dependency>
2)user_login.proto
syntax = "proto3";
// 转成java后所在包
option java_package = "com.tencent.rating.audi_model_api.pb";
// 转成java后的类名
option java_outer_classname = "MessageUserLogin";
// 转java后生成一个java文件
option java_multiple_files = false;message MessageUserLoginRequest {string username = 1;string password = 2;
}
message MessageUserLoginResponse {string access_token = 1;string username = 2;
}
编译:
protoc --proto_path=/data/ --java_out=./ /data/user_login.proto
3)创建springboot工程,编写config:
@Configuration
public class WebConfig {@BeanProtobufHttpMessageConverter protobufHttpMessageConverter() {return new ProtobufHttpMessageConverter();}/*** protobuf 反序列化 可以不用配置*/
// @Bean
// RestTemplate restTemplate(ProtobufHttpMessageConverter protobufHttpMessageConverter) {
// return new RestTemplate(Collections.singletonList(protobufHttpMessageConverter));
// }
}
4)编写contorller:
import java.util.UUID;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.tencent.rating.audi_model_api.pb.MessageUserLogin;@Controller
public class PbTestController { @RequestMapping(value = "/pbtest", produces = "application/x-protobuf")@ResponseBodypublic MessageUserLogin.MessageUserLoginResponse getPersonProto(@RequestBody MessageUserLogin.MessageUserLoginRequest request) {System.out.println("request:" + request.toString());MessageUserLogin.MessageUserLoginResponse.Builder builder = MessageUserLogin.MessageUserLoginResponse.newBuilder();builder.setAccessToken(UUID.randomUUID().toString()+"_res");builder.setUsername(request.getUsername()+"_res");return builder.build();}
}
然后启动sprinboot工程。监听8080端口
5)编写客户端请求:
public class PbTest {public static void main(String...strings) {try {String uri = "http://127.0.0.1:8080/clue/pbtest";MessageUserLogin.MessageUserLoginRequest.Builder builder = MessageUserLogin.MessageUserLoginRequest.newBuilder();builder.setUsername("tom");builder.setPassword("123456");HttpResponse response = doPost(uri, builder.build().toByteArray());MessageUserLogin.MessageUserLoginResponse messageUserLoginResponse = MessageUserLogin.MessageUserLoginResponse.parseFrom(response.getEntity().getContent());System.out.println("response:" + messageUserLoginResponse.toString());System.err.println(messageUserLoginResponse.getAccessToken());} catch (Exception e) {}}private static HttpResponse doPost(String uri, byte[] bytes) throws Exception {CloseableHttpResponse closeableHttpResponse = null;CloseableHttpClient httpclient = HttpClients.createDefault();try {HttpPost post = new HttpPost(uri);ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);InputStreamEntity inputStreamEntity = new InputStreamEntity(inputStream);post.setEntity(inputStreamEntity);post.addHeader("Content-Type", "application/x-protobuf");closeableHttpResponse = httpclient.execute(post);} catch (IOException e) {e.printStackTrace();} finally {// httpclient.close();}return closeableHttpResponse;}
}
2、servlet下实现protobuf:
1)创建servlet项目,编写servlet代码:
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import servlet_test.pb.MessageUserLogin;
import servlet_test.pb.MessageUserLogin.MessageUserLoginRequest;
import servlet_test.pb.MessageUserLogin.MessageUserLoginResponse.Builder;@WebServlet(urlPatterns = {"/syncServlet2"})
public class SyncServlet2 extends HttpServlet {private static final long serialVersionUID = 1L;protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {//解析请求InputStream stream=request.getInputStream();MessageUserLoginRequest mlr = MessageUserLogin.MessageUserLoginRequest.parseFrom(stream);System.out.println(mlr.toString());//创建响应Builder newBuilder = MessageUserLogin.MessageUserLoginResponse.newBuilder();newBuilder.setAccessToken(UUID.randomUUID().toString()+"_res");newBuilder.setUsername(mlr.getUsername()+"_res");response.setCharacterEncoding("UTF-8");ServletOutputStream out = response.getOutputStream();out.write(newBuilder.build().toByteArray());out.flush();out.close();}
}
2)客户端测试:
同上。
相关文章:
基于http的protobuf服务实现
本文介绍在http协议中,使用protobuf格式进行二进制数据通信。双方需设置http的header中ContentType为application/x-protobuf。 1、springboot下实现protobuf: 1)pom.xml <dependency><groupId>org.springframework.boot</g…...

基于uniapp的商城外卖小程序
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...
【CSS】Tailwind CSS
直接参考 Tailwind CSS 安装提供了四种方式。因为我常用构建工具搭建项目,所以选择 Using PostCSS 。 其中 tailwind.config.js 的配置可以改为: module.exports {content: [./index.html, ./src/**/*.{vue,js,ts,jsx,tsx}],theme: {extend: {},},pl…...

leetcode-电话号码组合(C CODE)
1. 题目 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits “23” 输出&#…...

Leetcode92. 反转链表 II
Every day a Leetcode 题目来源:92. 反转链表 II 解法1:模拟 注意 STL 的 reverse() 是左闭右开的。 代码: class Solution { public:ListNode *reverseBetween(ListNode *head, int left, int right){vector<int> nums getNums(…...
【算法作业记录】
插入排序 递归实现 直接插入 #将a[n]插入有序区间a[0,n-1]中 时间复杂度 O(n) def Insert(a,n):inwhile(i>0 and a[i-1]>a[i]):tmpa[i]a[i]a[i-1]a[i-1]tmpi-1return #直接插入排序 def Insertsort(a,n):for i in range(1,n):#【1,n-…...
回归预测、分类预测、时间序列预测 都有什么区别?
回归预测、分类预测和时间序列预测都是统计和机器学习领域中的预测任务,它们在问题设置和解决的方式上有一些关键区别: 回归预测: 回归预测用于预测连续数值的输出,通常是实数。例如,预测房价、气温、销售额等连续型输…...

关于网络协议的若干问题(三)
1、当发送的报文出问题的时候,会发送一个 ICMP 的差错报文来报告错误,但是如果 ICMP 的差错报文也出问题了呢? 答:不会导致产生 ICMP 差错报文的有: ICMP 差错报文(ICMP 查询报文可能会产生 ICMP 差错报文…...

办公室人人在用的iTab桌面真的好用吗?
本人坐标北京,在一家中型互联网公司当社畜多年。最近发现一个奇怪的现象,我工位前后左右的同事都跟我在用一样的浏览器桌面——iTab新标签页。我表示莫非真的英雄所见略同? 我是去年1月份在刷B站时偶然刷到一条评论,有人分享自己…...
循环中的else语句
while 循环else结构: 循环可以和else配合使用,else下方缩进的代码指的是当循环正常结束之后要执行的代码. 需求:女朋友生气了,要惩罚:连续说5遍“老婆大人,我错了”,如果道歉正常完毕后女朋友就原谅我了:…...

三.镜头知识之FOV
三.镜头知识之视场角 最近试了很多sensor, 每次在选镜头时都对其提到的FOV参数一头雾水。不同的sensor要配不同的镜头,而不同的镜头由于焦距的不同,FOV也不一样。这其中有什么联系呢?FOV又分为HFOV(水平), VFOV( 垂直)…...

分布式事务入门
文章目录 分布式事务问题本地事务分布式事务演示分布式事务问题 理论基础CAP定理一致性可用性分区容错矛盾 BASE理论 SeataSeata的架构部署TC服务微服务集成seata 动手实践XA模式两阶段提交Seata的XA模型实现XA模式 AT模式Seata的AT模型流程梳理脏写问题实现AT模式 TCC模式流程…...
Ubuntu的中文乱码问题
一、Ubuntu的中文乱码问题 sudo apt-get install language-pack-zh-hans 二、修改/etc/environment(在文件的末尾追加): LANG"zh_CN.UTF-8" LANGUAGE"zh_CN:zh:en_US:en" 三、修改/var/lib/locales/supported.d/loca…...

[GXYCTF2019]Ping Ping Ping - RCE(空格、关键字绕过[3种方式])
[GXYCTF2019]Ping Ping Ping 1 解题流程1.1 小试牛刀1.2 三种解法1.2.1 解法一:变量定义拼接绕过1.2.2 解法二:base64编码绕过1.2.3 解法三:内联执行绕过2 思考总结1 解题流程 1.1 小试牛刀 1、提示?ip,结合题目名称,我们直接输入?ip=127.0.0.1 PING 127.0.0.1 (127.…...

ceph 分布式存储与部署
目录 一、存储基础: 1.单机存储设备: 2. 单机存储的问题: 3. 商业存储解决方案: 4. 分布式存储: 5. 分布式存储的类型: 二、Ceph 简介: 三、Ceph 优势: 四、Ceph 架构:…...
Go 结构体深度探索:从基础到应用
1. 结构体概述 在计算机编程中,数据结构是组织、管理和存储数据的一种方式,它允许高效地执行各种操作。Go语言中的结构体(Struct)是这些数据结构中的一员,它为数据的组织提供了一种具体的方式。 结构体可以被视为是多…...

分布式系统开发技术中的CAP定理原理
分布式系统开发技术中的CAP定理原理 在分布式系统开发中,CAP定理(一致性、可用性和分区容忍性)是指导我们设计、开发和维护系统的核心原理。该定理阐述了分布式系统中一致性、可用性和扩展性之间无法同时满足的矛盾关系,为我们提…...
Mysql 报错 You can‘t specify target table ‘表名‘ for update in FROM clause
翻译为:不能先select出同一表中的某些值,再update这个表(在同一语句中) 多半是update在where条件后又Select了一次,所以报错 SQL: UPDATE a SET a.name 1 WHERE a.id in (SELECT a.id FROM a WHERE ISNULL(a.id)) …...
【DevOps】DevOps—基本概念
文章目录 1. DevOps2. CI/CD 1. DevOps 维基百科定义: DevOps是一组过程、方法与系统的统称,用于促进 开发、技术运营 和 质量保障(QA) 部门之间的沟通、协作与整合。我理解DevOps是一种软件管理思维模式。 为什么会有DevOps呢&…...

发行版兴趣小组季度动态:Anolis OS 支持大热 AI 软件栈,引入社区合作安全修复流程
发行版兴趣小组(Special Interest Group) :旨在为龙蜥社区构建、发布和维护一个稳定的操作系统发行版。 秋天的季节,发行版兴趣小组在 AI、安全、国产 OS 领域同样也是硕果累累。一起来看一下第三季度发行版兴趣小组的成果总结有…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...