基于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 领域同样也是硕果累累。一起来看一下第三季度发行版兴趣小组的成果总结有…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...