一、什么是protostuff
protostuff是一个开箱即用的序列化库,使用非常简单,相对其它序列化库,protostuff优势在于:
1、使用简单
Protobuf每次要编写接口定义文件,然后还要编译,操作太繁琐;
2、高性能
相对json等文本序列化库,protostuff是二进制的,因此性能比json等方式高;
可以说protostuff在高性能和使用成本上做了很好的取舍。
以下是其相关资料:
github:https://codechina.csdn.net/mirrors/protostuff/protostuff
官方文档:https://protostuff.github.io/docs/protostuff-runtime/
总的来说文档还是比较少的,原理需要自己结合代码看下。
二、使用
要使用protostuff非常简单,只要在需要序列化的成员上加上Tag注解,并写明顺序就行了,接下来我们看具体怎么使用;
1、加入依赖
<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、编写Demo
假设我们要序列化一个Student的类,定义如下:
public class Student {@Tag(1)private String name;@Tag(2)private String studentNo;@Tag(3)private int age;@Tag(4)private String schoolName;@Tag(5)private Address address;public Student(){this.address= new Address();}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getStudentNo() {return studentNo;}public void setStudentNo(String studentNo) {this.studentNo = studentNo;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getSchoolName() {return schoolName;}public void setSchoolName(String schoolName) {this.schoolName = schoolName;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}}
Address类定义如下:
ublic class Address {@Tag(1)private String province;@Tag(2)private String city;public Address(){}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}}
可以看到,我们只需要在类的属性上加个Tag的注解,并写明顺序,注意Tag的值必须从1开始。
然后就可以编写测试了:
Student student = new Student();student.setName("lance");student.setAge(28);student.setStudentNo("2011070122");student.setSchoolName("BJUT");student.setAddress(new Address());student.getAddress().setProvince("address");student.getAddress().setCity("hunan");//序列化Schema schema = RuntimeSchema.getSchema(student.getClass());byte[] bytes = ProtobufIOUtil.toByteArray(o, schema, LinkedBuffer.allocate());Student deSerializerResult = Student.class.newInstance();ProtostuffIOUtil.mergeFrom(bytes, deSerializerResult, schema);System.out.println("deSerializerResult:" + deSerializerResult.toString());}
正常的话可以输出Student对象了;
三、其它
1、Dubbo中使用
可以通过设置serialization属性为protostuff;
2、返回/接收客户端内容为protostuff协议
在Controller上加上相应的@Consumes和@Produces注解:
@Consumes({ MediaTypeExt.APPLICATION_PROTOSTUFF_V2})
@Produces({ MediaTypeExt.APPLICATION_PROTOSTUFF_V2})
四、注意事项
1、Tag值在父类和子类中唯一;
如果父类已经定义了Tag(11),则子类则不能用11这个Tag了;
2、成员为对象的,Tag号可以从1开始
像上面的Student有个Address成员,它的成员的Tag号从1开始,这个不会造成数据覆盖;




