java序列化之protobuf

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package  com.book.core.test;
 
import  java.math.BigDecimal;
import  java.util.ArrayList;
import  java.util.List;
 
import  com.book.core.model.Type;
import  com.book.core.serializable.SerializationUtil;
import  com.dyuproject.protostuff.LinkedBuffer;
import  com.dyuproject.protostuff.ProtobufIOUtil;
import  com.dyuproject.protostuff.ProtostuffIOUtil;
import  com.dyuproject.protostuff.Schema;
import  com.dyuproject.protostuff.runtime.RuntimeSchema;
 
/**
  * ProtoStuff测试
  * @author liweihan
  *
  */
public  class  TestProtoStuff {
     public  static  void  main(String[] args)  throws  Exception {
         
         /**
          * *********** 测试1 : 原始的序列化对象 ************
          */
         //序列化
         System.out.println( " ========= 序列化开始:"  );
         Schema<Type> schema = RuntimeSchema.getSchema(Type. class );
         Type type =  new  Type();
         type.setCityId( 1 );
         type.setPrice( new  BigDecimal( 100 ));
         type.setTypeName( "韩超" );
         
         LinkedBuffer buffer = LinkedBuffer.allocate( 1024 );
         byte [] data = ProtobufIOUtil.toByteArray(type, schema, buffer);
         System.out.println( "序列化后的大小:"  + data.length +  " 字节 !" );
         
         //反序列化
         System.out.println( " ========= 反序列化开始:"  );
         Type type2 =  new  Type();
         ProtobufIOUtil.mergeFrom(data, type2, schema);
         System.out.println( " ====== 反序列化后的结果为:cityId:"  + type2.getCityId() 
                 " ,typeName:"  + type2.getTypeName() 
                 " , price:"  + type2.getPrice());
         
         
         /**
          * ************ 测试2 :单独序列化集合 **************
          */
         Type t1 =  new  Type();
         t1.setId( 1 );
         t1.setCityId( 1 );
         t1.setPrice( new  BigDecimal( 1 ));
         t1.setTypeName( "TestHan" );
         
         List<Type> list1 =  new  ArrayList<Type>();
         list1.add(t1);
         list1.add(type);
         
         System.out.println( " *********** 序列化开始: " );
         List< byte []> result = serializeProtoStuffTypeList(list1);
         System.out.println( "序列化后集合的大小:"  + result.size());
         
         System.out.println( " *********** 反序列化开始: " );
         List<Type> l = deserializeProtoStuffToTypeList(result);
         System.out.println( " 反序列化后的集合大小为:"  + l.size() +  " , name1:"  + l.get( 0 ).getTypeName());
         
         /*********** 测试 3 *****************/
         Type type1 =  new  Type();
         type1.setCityId( 2 );
         type1.setPrice( new  BigDecimal( 100 ));
         type1.setTypeName( "太" );
         
         System.out.println( " ------ 序列化开始:" );
         byte [] type1Ser = SerializationUtil.object2Bytes_obj(type1);
         System.out.println( " ------- 序列化后的大小:"  + type1Ser.length);
         
         System.out.println( " ------ 反序列化开始:" );
         Type type1Result = (Type)SerializationUtil.bytes2Object(type1Ser);
         System.out.println( " ====== 反序列化后的结果为:cityId:"  + type1Result.getCityId() 
                 " ,typeName:"  + type1Result.getTypeName() 
                 " , price:"  + type1Result.getPrice());
         
     
         /******************** 测试4 :序列化集合 **********************/
         Type t2 =  new  Type();
         t2.setId( 2 );
         t2.setCityId( 2 );
         t2.setPrice( new  BigDecimal( 23 ));
         t2.setTypeName( "ZHANG" );
         
         ArrayList<Type> list2 =  new  ArrayList<Type>();
         list2.add(t2);
         list2.add(t1);
         
         System.out.println( " ++++++++++++++   序列化开始: " );
         byte [] result2 =  SerializationUtil.object2Bytes(list2);
         System.out.println( " 序列化的大小: "  + result2.length);
         
         System.out.println( " ++++++++++++++   序列化结束: " );
         List<Type> listResult = (List<Type>)SerializationUtil.bytes2Object(result2);
         for  (Type t: listResult) {
             System.out.println(t.getTypeName());
         }
     }
     
     /**
      * 序列化Type的List集合
      * @param tList
      * @return
      */
     public  static  List< byte []> serializeProtoStuffTypeList(List<Type> tList) {
         if  (tList ==  null  || tList.size() <=  0 ) {
             return  null ;
         }
         
         List< byte []> bytes =  new  ArrayList< byte []>();
         Schema<Type> schema = RuntimeSchema.getSchema(Type. class );
         LinkedBuffer buffer = LinkedBuffer.allocate( 1024 );
         byte [] protostuff =  null ;
         for (Type t: tList) {
             try  {
                 protostuff = ProtostuffIOUtil.toByteArray(t, schema, buffer);
                 bytes.add(protostuff);
             catch  (Exception e) {
                 e.printStackTrace();
             finally  {
                 buffer.clear();
             }
         }
         
         return  bytes;
     }
     
     /**
      * 反序列化Type的List集合
      * @param bytesList
      * @return
      */
     public  static  List<Type> deserializeProtoStuffToTypeList(List< byte []> bytesList) {
         if  (bytesList ==  null  || bytesList.size() <=  0 ) {
             return  null ;
         }
         
         Schema<Type> schema = RuntimeSchema.getSchema(Type. class );
         List<Type> list =  new  ArrayList<Type>();
         for  ( byte [] bs : bytesList) {
             Type type =  new  Type();
             ProtostuffIOUtil.mergeFrom(bs, type, schema);
             list.add(type);
         }
         return  list;
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package  com.book.core.serializable;
 
import  java.io.Serializable;
 
public  class  SerializationUtil {
     
     public  static  ProtostuffSerializer protostuffSerializer;
 
     static  {
         protostuffSerializer =  new  ProtostuffSerializer();
     }
 
 
     public  static  byte [] object2Bytes(Serializable obj)  throws  Exception {
         if  (obj ==  null ) {
             return  null ;
         }
 
         return  protostuffSerializer.serialize(obj);
 
/*      ByteArrayOutputStream bo = new ByteArrayOutputStream();
         ObjectOutputStream oo = new ObjectOutputStream(bo);
         oo.writeObject(obj);
         bo.close();
         oo.close();
         return bo.toByteArray();*/
     }
     
     /**
      * 序列化【序列化对象不需要实现Serializable】
      * @param obj
      * @return
      * @throws Exception
      */
     public static byte[] object2Bytes_obj(Object obj) throws Exception {
         if (obj == null) {
             return null;
         }
         
         return protostuffSerializer.serialize(obj);
     }
 
     public static byte[][] objects2Bytes(Serializable[] obj) throws Exception {
         if (obj == null) {
             return null;
         }
         byte[][] many = new byte[obj.length][];
         for(int i=0;i<obj.length;i++){
             many[i] = object2Bytes(obj[i]);
         }
         return many;
     }
 
 
     public static Object bytes2Object(byte[] objBytes) throws Exception {
         if (objBytes == null || objBytes.length == 0) {
             return null;
         }
         Object obj = protostuffSerializer.deserialize(objBytes);
         return obj;
 
         /*ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
         ObjectInputStream oi = new ObjectInputStream(bi);
         obj = oi.readObject();
         bi.close();
         oi.close();
         return obj;*/
     }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package  com.book.core.serializable;
 
 
import  com.dyuproject.protostuff.LinkedBuffer;
import  com.dyuproject.protostuff.ProtostuffIOUtil;
import  com.dyuproject.protostuff.Schema;
import  com.dyuproject.protostuff.runtime.RuntimeSchema;
 
import  java.util.concurrent.ConcurrentHashMap;
 
public  class  ProtostuffSerializer {
     
     private  static  ConcurrentHashMap<Class<?>, Schema<?>> cachedSchema =  new  ConcurrentHashMap<Class<?>, Schema<?>>();
 
     public  <T>  byte [] serialize( final  T source) {
         VO<T> vo =  new  VO<T>(source);
 
         final  LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
         try  {
             final  Schema<VO> schema = getSchema(VO. class );
             return  serializeInternal(vo, schema, buffer);
         catch  ( final  Exception e) {
             throw  new  IllegalStateException(e.getMessage(), e);
         finally  {
             buffer.clear();
         }
     }
 
     public  <T> T deserialize( final  byte [] bytes) {
         try  {
             Schema<VO> schema = getSchema(VO. class );
             VO vo = deserializeInternal(bytes, schema.newMessage(), schema);
             if  (vo !=  null  && vo.getValue() !=  null ) {
                 return  (T) vo.getValue();
             }
         catch  ( final  Exception e) {
             throw  new  IllegalStateException(e.getMessage(), e);
         }
         return  null ;
     }
 
     private  <T>  byte [] serializeInternal( final  T source,  final  Schema<T> schema,  final  LinkedBuffer buffer) {
         return  ProtostuffIOUtil.toByteArray(source, schema, buffer);
     }
 
     private  <T> T deserializeInternal( final  byte [] bytes,  final  T result,  final  Schema<T> schema) {
         ProtostuffIOUtil.mergeFrom(bytes, result, schema);
         return  result;
     }
 
     private  static  <T> Schema<T> getSchema(Class<T> clazz) {
         @SuppressWarnings ( "unchecked" )
         Schema<T> schema = (Schema<T>) cachedSchema.get(clazz);
         if  (schema ==  null ) {
             schema = RuntimeSchema.createFrom(clazz);
             cachedSchema.put(clazz, schema);
         }
         return  schema;
     }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package  com.book.core.serializable;
 
import  java.io.Serializable;
 
/**
  * Created by yijunzhang on 14-4-2.
  */
public  class  VO<T>  implements  Serializable {
 
     private  T value;
 
     public  VO(T value) {
         this .value = value;
     }
 
     public  VO() {
     }
 
     public  T getValue() {
         return  value;
     }
 
     @Override
     public  String toString() {
         return  "VO{"  +
                 "value="  + value +
                 '}' ;
     }
 
     @Override
     public  boolean  equals(Object o) {
         if  ( this  == o)  return  true ;
         if  (!(o  instanceof  VO))  return  false ;
         VO vo = (VO) o;
         if  (value !=  null  ? !value.equals(vo.value) : vo.value !=  null return  false ;
         return  true ;
     }
 
     @Override
     public  int  hashCode() {
         return  value !=  null  ? value.hashCode() :  0 ;
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package  com.book.core.model;
 
import  java.math.BigDecimal;
 
public  class  Type {
     private  Integer id;
 
     private  String typeName;
 
     private  BigDecimal price;
 
     private  Integer cityId;
 
     public  Integer getId() {
         return  id;
     }
 
     public  void  setId(Integer id) {
         this .id = id;
     }
 
     public  String getTypeName() {
         return  typeName;
     }
 
     public  void  setTypeName(String typeName) {
         this .typeName = typeName ==  null  null  : typeName.trim();
     }
 
     public  BigDecimal getPrice() {
         return  price;
     }
 
     public  void  setPrice(BigDecimal price) {
         this .price = price;
     }
 
     public  Integer getCityId() {
         return  cityId;
     }
 
     public  void  setCityId(Integer cityId) {
         this .cityId = cityId;
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
< dependency >
   < groupId >com.dyuproject.protostuff</ groupId >
   < artifactId >protostuff-core</ artifactId >
   < version >${protostuff.version}</ version >
</ dependency >
< dependency >
   < groupId >com.dyuproject.protostuff</ groupId >
   < artifactId >protostuff-runtime</ artifactId >
   < version >${protostuff.version}</ version >
</ dependency >
< dependency >
   < groupId >com.dyuproject.protostuff</ groupId >
   < artifactId >protostuff-api</ artifactId >
   < version >${protostuff.version}</ version >
</ dependency >
< dependency >
   < groupId >com.dyuproject.protostuff</ groupId >
   < artifactId >protostuff-collectionschema</ artifactId >
   < version >${protostuff.version}</ version >
</ dependency >
1
< protostuff.version >1.0.8</ protostuff.version >

序列化的几种方式

http://my-corner.iteye.com/blog/1776512



Java序列化简单了解

http://hanchaohan.blog.51cto.com/2996417/922470



jprotobuf的简单了解

https://github.com/jhunters/jprotobuf



java序列化/反序列化之xstream、protobuf、protostuff 的比较与使用例子

http://www.cnblogs.com/xiaoMzjm/p/4555209.html



注意事项:String对象要不要序列化的问题,个人建议不要。

假如,我们调用一个接口:http://api.tv.xxxx.com/v4/video/info/3784655.json?site=1&api_key=695fe827ffeb7d74260a813025970bd5&plat=17&partner=1&sver=3.5&poid=1&aid=0

返回一个JSON类型的字符串。


我们需要把字符串存入redis缓存中,我们有3中方式缓存

1:直接存储String对象

2:序列化String对象后,存入redis

3:转为JSON对象,序列化JSON对象后,存入redis


下面我们打印一下三种方式,所占用的空间大小,我们发现序列化后,对象大小都普通增大了。

这样,会多占用我们缓存的空间。

如果是json string类型的 可以不序列化 redis的客户端会做getbytes做字节流的转换 其实就是做string的序列化

wKioL1m1_nbSZV5NAAEfjxBdShA472.jpg

wKiom1m1_pyCUX3fAACiyvpqmlI303.jpg




     本文转自韩立伟 51CTO博客,原文链接:http://blog.51cto.com/hanchaohan/1962798,如需转载请自行联系原作者




相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
存储 Java 数据库
|
3月前
|
存储 算法 Java
从零开始学习 Java:简单易懂的入门指南之IO序列化、打印流、压缩流(三十三)
从零开始学习 Java:简单易懂的入门指南之IO序列化、打印流、压缩流(三十三)
|
3月前
|
分布式计算 Java 大数据
IO流【Java对象的序列化和反序列化、File类在IO中的作用、装饰器模式构建IO流体系、Apache commons-io工具包的使用】(四)-全面详解(学习总结---从入门到深化)
IO流【Java对象的序列化和反序列化、File类在IO中的作用、装饰器模式构建IO流体系、Apache commons-io工具包的使用】(四)-全面详解(学习总结---从入门到深化)
53 0
|
16天前
|
存储 Java
Java输入输出:解释一下序列化和反序列化。
Java中的序列化和反序列化是将对象转换为字节流和反之的过程。ObjectOutputStream用于序列化,ObjectInputStream则用于反序列化。示例展示了如何创建一个实现Serializable接口的Person类,并将其序列化到文件,然后从文件反序列化回Person对象。
25 5
|
1月前
|
存储 缓存 JSON
什么是Java序列化,它有哪些重要性
什么是Java序列化,它有哪些重要性
|
2月前
|
存储 自然语言处理 Java
java缓冲流、转换流、序列化流、打印流
java缓冲流、转换流、序列化流、打印流介绍
|
2月前
|
C++
[序列化协议] --- protobuf
[序列化协议] --- protobuf
24 0
|
3月前
|
XML JSON Java
java项目中使用protobuf扫盲笔记
最近公司 Java 项目中有用到 protobuf,查了些资料还是一脸迷茫。
52 1
|
3月前
|
JSON Java fastjson
Java中的JSON序列化和反序列化
Java中的JSON序列化和反序列化
|
3月前
|
存储 Java 数据安全/隐私保护
Java序列化有什么作用
Java序列化有什么作用