最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot集成ProtoBuf的實例

 更新時間:2022年03月16日 11:16:25   作者:xrq0508  
這篇文章主要介紹了Springboot集成ProtoBuf的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Springboot集成ProtoBuf

ProtoBuf是一種序列化和解析速度遠高于JSON和XML的數(shù)據(jù)格式,項目中使用了CouchBase作為緩存服務器,從數(shù)據(jù)庫中拿到數(shù)據(jù)后通過protobuf序列化后放入CouchBase作為緩存,查詢數(shù)據(jù)的時候解壓并反序列化成數(shù)據(jù)對象,下面是ProtoBuf的具體使用方法

1、pom.xml引入相關依賴

<dependency>
? ? <groupId>com.google.protobuf</groupId>
?? ?<artifactId>protobuf-java</artifactId>
?? ?<version>3.5.0</version>
</dependency>
<dependency>
?? ?<groupId>io.protostuff</groupId>
?? ?<artifactId>protostuff-core</artifactId>
?? ?<version>1.4.0</version>
</dependency>
<dependency>
?? ?<groupId>io.protostuff</groupId>
?? ?<artifactId>protostuff-runtime</artifactId>
?? ?<version>1.4.0</version>
</dependency>

2、新建序列化工具類ProtoBufUtil.java

package com.xrq.demo.utils;?
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
?
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.objenesis.Objenesis;
import org.springframework.objenesis.ObjenesisStd;
?
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
?
/**
?* ProtoBufUtil 轉換工具類
?*?
?* @author XRQ
?*
?*/
public class ProtoBufUtil {
?? ?private static Logger log = LoggerFactory.getLogger(ProtoBufUtil.class);
?? ?private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();
?
?? ?private static Objenesis objenesis = new ObjenesisStd(true);
?
?? ?@SuppressWarnings("unchecked")
?? ?private static <T> Schema<T> getSchema(Class<T> cls) {
?? ??? ?Schema<T> schema = (Schema<T>) cachedSchema.get(cls);
?? ??? ?if (schema == null) {
?? ??? ??? ?schema = RuntimeSchema.createFrom(cls);
?? ??? ??? ?if (schema != null) {
?? ??? ??? ??? ?cachedSchema.put(cls, schema);
?? ??? ??? ?}
?? ??? ?}
?? ??? ?return schema;
?? ?}
?
?? ?public ProtoBufUtil() {
?? ?}
?
?? ?@SuppressWarnings({ "unchecked" })
?? ?public static <T> byte[] serializer(T obj) {
?? ??? ?Class<T> cls = (Class<T>) obj.getClass();
?? ??? ?LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
?? ??? ?try {
?? ??? ??? ?Schema<T> schema = getSchema(cls);
?? ??? ??? ?return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
?? ??? ?} catch (Exception e) {
?? ??? ??? ?log.error("protobuf序列化失敗");
?? ??? ??? ?throw new IllegalStateException(e.getMessage(), e);
?? ??? ?} finally {
?? ??? ??? ?buffer.clear();
?? ??? ?}
?? ?}
?
?? ?public static <T> T deserializer(byte[] bytes, Class<T> clazz) {
?? ??? ?try {
?? ??? ??? ?T message = (T) objenesis.newInstance(clazz);
?? ??? ??? ?Schema<T> schema = getSchema(clazz);
?? ??? ??? ?ProtostuffIOUtil.mergeFrom(bytes, message, schema);
?? ??? ??? ?return message;
?? ??? ?} catch (Exception e) {
?? ??? ??? ?log.error("protobuf反序列化失敗");
?? ??? ??? ?throw new IllegalStateException(e.getMessage(), e);
?? ??? ?}
?? ?}
?
}

3、新建實體類User.java

注:重點是@Tag標簽需要按照順序往下排,如果需要新增字段,只能接著往下排,不能改變已存在的標簽序號

package com.xrq.demo.bo;?
import java.io.Serializable;
import java.util.Date; ?
import io.protostuff.Tag;
?
/**
?* 用戶信息類
?*?
?* @ClassName: User
?* @author XRQ
?* @date 2019年4月30日
?*/
public class User implements Serializable
{
? ? private static final long serialVersionUID = 1L;
?
? ? // 用戶ID
? ? @Tag(1)
? ? private int userId;
?
? ? // 用戶類型
? ? @Tag(2)
? ? private int userTypeId;
?
? ? // 用戶名?
? ? @Tag(3)
? ? private String userName;
?
? ? // 創(chuàng)建時間
? ? @Tag(4)
? ? private Date createDateTime;?
? ? public int getUserId()
? ? {
?
? ? ? ? return userId;
? ? }
?
? ? public void setUserId(int userId)
? ? {
?
? ? ? ? this.userId = userId;
? ? }
?
? ? public int getUserTypeId()
? ? {
?
? ? ? ? return userTypeId;
? ? }
?
? ? public void setUserTypeId(int userTypeId)
? ? {
?
? ? ? ? this.userTypeId = userTypeId;
? ? }
?
? ? public String getUserName()
? ? {
?
? ? ? ? return userName;
? ? }
?
? ? public void setUserName(String userName)
? ? {
?
? ? ? ? this.userName = userName;
? ? }
?
? ? public Date getCreateDateTime()
? ? {
?
? ? ? ? return createDateTime;
? ? }
?
? ? public void setCreateDateTime(Date createDateTime)
? ? {
?
? ? ? ? this.createDateTime = createDateTime;
? ? }
}

4、使用方式

User user = new User();
user.setUserId(1);
user.setUserTypeId(1);
user.setUserName("XRQ");
user.setCreateDateTime(new Date());
//序列化成ProtoBuf數(shù)據(jù)結構
byte[] userProtoObj= ProtoBufUtil.serializer(userInfo)
?
//ProtoBuf數(shù)據(jù)結構反序列化成User對象
User newUserObj = ProtoBufUtil.deserializer(userProtoObj, User.class))

ProtoBuf+Java+Springboot+IDEA應用 

什么是Protobuf

1.Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內(nèi)部的混合語言數(shù)據(jù)標準;

2.Protocol Buffers 是一種輕便高效的結構化數(shù)據(jù)存儲格式,可以用于結構化數(shù)據(jù)串行化,或者說序列化。它很適合做數(shù)據(jù)存儲或 RPC 數(shù)據(jù)交換格式??捎糜谕ㄓ崊f(xié)議、數(shù)據(jù)存儲等領域的語言無關、平臺無關、可擴展的序列化結構數(shù)據(jù)格式;

3.形式為.proto結尾的文件;

應用環(huán)境

近期接觸公司的網(wǎng)約車接口對接項目,第三方公司限定了接口的數(shù)據(jù)用protobuf格式序列化后,通過AES128加密后傳輸。

開發(fā)環(huán)境

Java+Spring boot+IDEA+Windows

新建Spring boot項目 在IDEA開發(fā)工具中安裝protobuf插件

添加配置maven依賴(可能一開始自己的項目中存在固有的配置,不要刪除,在對應的地方添加下面的配置即可,不需要修改)

<dependency>
	<groupId>io.protostuff</groupId>
	<artifactId>protostuff-runtime</artifactId>
	<version>1.4.0</version>
</dependency>
<plugin>
	<groupId>org.xolstice.maven.plugins</groupId>
	<artifactId>protobuf-maven-plugin</artifactId>
	<version>0.5.0</version>
	<configuration>
	<protocArtifact>
		com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}
	</protocArtifact>
	<pluginId>grpc-java</pluginId>
	</configuration>
	<executions>
		<execution>
			<goals>
				<goal>compile</goal>
                <goal>compile-custom</goal>
            </goals>
        </execution>
    </executions>
</plugin>

寫項目對應的.proto文件(這里貼一部分代碼)

// 版本號
syntax = "proto2";
// 打包路徑
option java_package="XXX1";
// Java文件名
option java_outer_classname="XXX2";
// 屬性信息
message BaseInfo {
	// 公司標識
	required string CompanyId       = 1;
	// 公司名稱
	required string CompanyName     = 2;
    // 操作標識
	required uint32 Flag            = 3;
	// 更新時間
	required uint64 UpdateTime      = 4;
}

.proto文件存在項目路徑

生成.java文件方式(點擊項目中的.proto文件,找到對應的maven依賴,雙擊標識2對應的protobuf:compile文件)

運行成功之后在對應路徑下查看生成的.java文件

生成的Java文件即可使用(如果在業(yè)務中.proto文件很大,生成的Java大小超出IDEA默認的2.5M,生成的Java文件將被IDEA誤認為不是Java文件,導致生成的Java文件不可使用,這時需要修改IDEA的配置文件,將默認的大小修改,重啟IDEA即可) 進行數(shù)據(jù)序列化

List<BaseInfo> baseInfoList = baseInfoMapper.selectAll();
XXX2.OTIpcList.Builder listBuilder = XXX2.OTIpcList.newBuilder();
XXX2.OTIpc.Builder otipcBuilder = XXX2.OTIpc.newBuilder();
otipcBuilder.setCompanyId(ProjectConstant.COMPANY_ID);
otipcBuilder.setSource(ProjectConstant.COMPANY_SOURCE);
otipcBuilder.setIPCType(OTIpcDef.IpcType.baseInfoCompany);
for(int i=0;i<baseInfoList .size();i++){
	try{
		XXX2.BaseInfo.Builder baseInfoBuilder = XXX2.BaseInfo.newBuilder();
		baseInfoBuilder .setCompanyId(baseInfoList .get(i).getCompanyid());
		baseInfoBuilder .setCompanyName(baseInfoList .get(i).getCompanyname());
		baseInfoBuilder .setFlag(baseInfoList .get(i).getFlag());
		baseInfoBuilder .setUpdateTime(baseInfoList .get(i).getUpdatetime());
		for(int j=0;j<10;j++) {
			otipcBuilder.addBaseInfo(baseInfoBuilder .build());
		}
	}
	catch (Exception e){
		LoggerUtils.info(getClass(),e.getMessage());
	}
}
listBuilder.addOtpic(otipcBuilder);

進行數(shù)據(jù)AES128位加密

public static String sendScreate(OTIpcDef.OTIpcList.Builder listBuilder) {
        String screateKeyString = getSecretKey();
        String screateKey = screateKeyString.split(";")[1];
        String screateValue = screateKeyString.split(";")[0];
        OTIpcDef.OTIpcList list = listBuilder.build();
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            list.writeTo(output);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] data = null;
        try{
            byte[] keyByte = new byte[screateValue.length()/2];
            for(int j=0;j<screateValue.length()/2;j++) {
                byte b = (byte) ((Integer.valueOf(String.valueOf(screateValue.charAt(j*2)), 16) << 4) |
                        Integer.valueOf(String.valueOf(screateValue.charAt(j*2+1)), 16));
                keyByte[j] = b;
		}
		Key secretKey= new SecretKeySpec(keyByte,"AES");
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		Cipher cipher= Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
		cipher.init(Cipher.ENCRYPT_MODE, secretKey);
		data = cipher.doFinal(output.toByteArray());
		sendPostJSON(screateKey, data);
		return "success";
	} catch(Exception e){
		e.printStackTrace();
	}
	return null;
}

小結一下:經(jīng)驗證,Protobuf 序列化相比XML,JSON性能更好,在Protobuf 官網(wǎng)看到在創(chuàng)建對象,將對象序列化為內(nèi)存中的字節(jié)序列,然后再反序列化的整個過程中相比其他相似技術的性能測試結果圖,但是在通用性上會存在局限性,功能相對簡單,不適合用來描述數(shù)據(jù)結構。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 解讀String字符串拼接的原理

    解讀String字符串拼接的原理

    這篇文章主要介紹了關于String字符串拼接的原理,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • SpringMVC請求流程源碼解析

    SpringMVC請求流程源碼解析

    這篇文章主要介紹了SpringMVC請求流程源碼分析,包括springmvc使用,SpringMVC啟動過程及SpringMVC請求過程,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • Java8 Zip 壓縮與解壓縮的實現(xiàn)

    Java8 Zip 壓縮與解壓縮的實現(xiàn)

    這篇文章主要介紹了Java8 Zip 壓縮與解壓縮的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • SpringBoot使用FFmpeg實現(xiàn)M3U8切片轉碼播放

    SpringBoot使用FFmpeg實現(xiàn)M3U8切片轉碼播放

    FFmpeg是一個開源跨平臺的多媒體處理工具套件,它支持音頻、視頻文件的編碼、解碼、流媒體傳輸以及轉換等多種操作,本文小編給大家介紹了SpringBoot使用FFmpeg實現(xiàn)M3U8切片轉碼播放的操作,需要的朋友可以參考下
    2024-08-08
  • 淺談Java的SPI技術

    淺談Java的SPI技術

    這篇文章主要介紹了Java的SPI技術的相關資料,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • MyBatisPlus條件構造器圖文實例詳解

    MyBatisPlus條件構造器圖文實例詳解

    這篇文章主要介紹了MyBatisPlus條件構造器,了解內(nèi)部原理是為了幫助我們做擴展,同時也是驗證了一個人的學習能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會的
    2023-01-01
  • 將15位身份證補全為18位身份證的算法示例詳解

    將15位身份證補全為18位身份證的算法示例詳解

    這篇文章主要給大家介紹了關于將15位身份證補全為18位身份證算法的相關資料,文中通過示例代碼給大家介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編一起來學習學習吧。
    2017-06-06
  • 深入理解Java設計模式之適配器模式

    深入理解Java設計模式之適配器模式

    這篇文章主要介紹了JAVA設計模式之適配器模式的的相關資料,文中示例代碼非常詳細,供大家參考和學習,感興趣的朋友可以了解
    2021-11-11
  • Java Volatile關鍵字實現(xiàn)原理過程解析

    Java Volatile關鍵字實現(xiàn)原理過程解析

    這篇文章主要介紹了Java Volatile關鍵字實現(xiàn)原理過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Java中的@Accessors使用詳解

    Java中的@Accessors使用詳解

    這篇文章主要介紹了Java中的@Accessors使用詳解,@RequiredArgsConstructor是Lombok的一個注解,簡化了我們對setter和getter方法操作,它可以作用在類上,也可以作用在類的單個屬性上,需要的朋友可以參考下
    2024-01-01

最新評論

共和县| 海南省| 乐清市| 重庆市| 灵丘县| 大理市| 宣城市| 哈巴河县| 黄陵县| 许昌县| 新竹市| 新泰市| 通河县| 安岳县| 沁水县| 武冈市| 迁安市| 金乡县| 吉林省| 永顺县| 北安市| 临桂县| 保德县| 老河口市| 锦州市| 邛崃市| 靖江市| 阳西县| 高雄县| 灌云县| 新兴县| 莎车县| 张家口市| 梁山县| 濮阳市| 鄯善县| 黑龙江省| 宜州市| 合作市| 舒城县| 平乐县|