Protostuff序列化和反序列化使用说明

转载自:《Protostuff序列化和反序列化使用说明》

google原生的protobuffer使用起来相当麻烦,首先要写.proto文件,然后编译.proto文件,生成对应的.java文件,鄙人试了一次,发现真的很麻烦。而protostuff的官方网站(http://www.protostuff.io/documentation/runtime-schema/),对于智商比较低的小编来说也略显生涩,于是鄙人就根据项目中用到的protostuff,撰写此文,以方便自己和他人加深印象和学习。

 

1. maven依赖

        <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工具类:ProtoBufUtil.java

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
 
/**
 * Created by zhangzh on 2017/2/20.
 */
public class ProtoBufUtil {
    public ProtoBufUtil() {
    }
 
    public static <T> byte[] serializer(T o) {
        Schema schema = RuntimeSchema.getSchema(o.getClass());
        return ProtobufIOUtil.toByteArray(o, schema, LinkedBuffer.allocate(256));
    }
 
    public static <T> T deserializer(byte[] bytes, Class<T> clazz) {
 
        T obj = null;
        try {
            obj = clazz.newInstance();
            Schema schema = RuntimeSchema.getSchema(obj.getClass());
            ProtostuffIOUtil.mergeFrom(bytes, obj, schema);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
 
        return obj;
    }
}

3. bean类Student.java   

import io.protostuff.Tag;
 
/**
 * Created by zhangzh on 2017/2/20.
 */
public class Student {
 
    @Tag(1)
    private String name;
    @Tag(2)
    private String studentNo;
    @Tag(3)
    private int age;
    @Tag(4)
    private String schoolName;
 
   // 关于@Tag,要么所有属性都有@Tag注解,要么都没有,不能一个类中只有部分属性有@Tag注解
 
    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;
    }
 
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", studentNo='" + studentNo + '\'' +
                ", age=" + age +
                ", schoolName='" + schoolName + '\'' +
                '}';
    }
}

4.test类ProtoBufUtilTest.java  

import java.util.Arrays;
 
/**
 * Created by zhangzh on 2017/2/20.
 */
public class ProtoBufUtilTest {
 
    public static void main(String[] args) {
 
        Student student = new Student();
        student.setName("lance");
        student.setAge(28);
        student.setStudentNo("2011070122");
        student.setSchoolName("BJUT");
 
        byte[] serializerResult = ProtoBufUtil.serializer(student);
 
        System.out.println("serializer result:" + Arrays.toString(serializerResult));
 
        Student deSerializerResult = ProtoBufUtil.deserializer(serializerResult,Student.class);
 
        System.out.println("deSerializerResult:" + deSerializerResult.toString());
    }
 
}

5.输出结果

serializer result:[10, 5, 108, 97, 110, 99, 101, 18, 10, 50, 48, 49, 49, 48, 55, 48, 49, 50, 50, 24, 28, 34, 4, 66, 74, 85, 84]
deSerializerResult:Student{name='lance', studentNo='2011070122', age=28, schoolName='BJUT'}

看,简单吧!

 

 参考资料:1. protostuff官方网站.

                     2. Protostuff序列化.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
protostuff 是一个支持各种格式的一个序列Java类库,包括 JSON、XML、YAML等格式。示例代码:public class UserSchema implements Schema<User> {     public boolean isInitialized(User user)     {         return user.getEmail() != null;     }     public void mergeFrom(Input input, User user) throws IOException     {         while(true)         {             int number = input.readFieldNumber(this);             switch(number)             {                 case 0:                     return;                 case 1:                     user.setEmail(input.readString());                     break;                 case 2:                     user.setFirstName(input.readString());                     break;                 case 3:                     user.setLastName(input.readString());                     break;                 case 4:                     if(message.friends == null)                         message.friends = new ArrayList<User>();                     message.friends.add(input.mergeObject(null, this));                     break;                 default:                     input.handleUnknownField(number, this);             }         }     }     public void writeTo(Output output, User user) throws IOException     {         if(user.getEmail() == null)             throw new UninitializedMessageException(user, this);         output.writeString(1, user.getEmail(), false);         if(user.getFirstName() != null)             output.writeString(2, user.getFirstName(), false);         if(user.getLastName() != null)             output.writeString(3, user.getLastName(), false);         if(message.friends != null)         {             for(User friend : message.friends)             {                 if(friend != null)                     output.writeObject(4, friend, this, true);             }         }     }     public User newMessage()     {         return new User();     }     public Class<User> typeClass()     {         return User.class;     }     public String messageName()     {         return User.class.getSimpleName();     }     public String messageFullName()     {         return User.class.getName();     }     // the mapping between the field names to the field numbers.     public String getFieldName(int number)     {         switch(number)         {             case 1:                 return "email";             case 2:                 return "firstName";             case 3:                 return "lastName";             case 4:                 return "friends";             default:                 return null;         }     }     public int getFieldNumber(String name)     {         Integer number = fieldMap.get(name);         return number == null ? 0 : number.intValue();     }     private static final HashMap<String,Integer> fieldMap = new HashMap<String,Integer>();         static     {         fieldMap.put("email", 1);         fieldMap.put("firstName", 2);         fieldMap.put("lastName", 3);         fieldMap.put("friends", 4);     } } 标签:protostuff
首先,需要在前端项目中引入 `protostuff` 库。可以通过 npm 安装或者使用 `<script>` 标签引入。 接下来,需要定义用于序列序列的数据结构。可以使用 protobuf 定义数据结构,然后通过 `protostuff` 的 `Message` 类来创建 JavaScript 类。 例如,假设我们有一个 protobuf 文件定义了一个 `Person` 消息类型: ```protobuf syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 我们可以使用 `protoc` 编译器来生成对应的 JavaScript 代码: ``` protoc --js_out=import_style=commonjs,binary:. person.proto ``` 然后在前端项目中引入生成的代码: ```javascript const ProtoBuf = require('protobufjs'); const proto = require('./person_pb'); // create a Person message const person = new proto.Person(); person.setName('Alice'); person.setAge(30); // serialize the message to a Uint8Array const buffer = proto.Person.encode(person).finish(); // deserialize the message from a Uint8Array const decodedPerson = proto.Person.decode(buffer); console.log(decodedPerson.getName()); // output: "Alice" console.log(decodedPerson.getAge()); // output: 30 ``` 在这个例子中,我们使用 `Person` 类来创建一个 `person` 对象,并设置其属性。然后将其序列为一个 `Uint8Array`,并在序列使用 `Person` 类来解码该数组并还原为 `decodedPerson` 对象。 需要注意的是,`protostuff` 库本身并不支持在浏览器中使用,因为它依赖于 Node.js 的 `Buffer` 类。但是可以使用一些类似 `buffer` 的库,如 `typedarray-to-buffer` 或 `base64-arraybuffer`,将 `Uint8Array` 转换为 `buffer`,然后再进行序列序列操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值