java序列化之protobuf

  1. 云栖社区>
  2. 博客>
  3. 正文

java序列化之protobuf

技术小胖子 2017-11-15 14:14:00 浏览613
展开阅读全文
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 != nullreturn 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,如需转载请自行联系原作者




网友评论

登录后评论
0/500
评论
技术小胖子
+ 关注