Protostuff使用入门[通俗易懂]

Protostuff使用入门[通俗易懂]ProtostuffThegoalofprotostuffistogenerateaschemawhetheratcompile-timeorruntimeandusethatforreading/writingtovariousformatsviatheprovidedIOlibs.SchemaAclassthatencapsu…

大家好,又见面了,我是你们的朋友全栈君。

Protostuff

The goal of protostuff is to generate a schema whether at compile-time or runtime and use that for reading/writing to various formats via the provided IO libs.

Schema

A class that encapsulates:

  • the serialization logic of an object
  • the deserialization logic of an object
  • the validation of an object’s required fields
  • the mapping of an object’s field names to field numbers
  • the instantiation of the object.

For existing objects, use protostuff-runtime which uses reflection.

示例

User类是个简单的pojo类:

package demo.domain;

import lombok.Data;
import java.util.List;

@Data
public class User { 
   
    private String firstName;
    private String lastName;
    private String email;
    private List<User> friends;
}

定义User的序列化逻辑:UserSchema

package demo.serializing;
import demo.domain.User;
import io.protostuff.Input;
import io.protostuff.Output;
import io.protostuff.Schema;
import io.protostuff.UninitializedMessageException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
public class UserSchema implements Schema<User> { 

private static final HashMap<String, Integer> fieldMap = new HashMap<>();
static { 

fieldMap.put("email", 1);
fieldMap.put("firstName", 2);
fieldMap.put("lastName", 3);
fieldMap.put("friends", 4);
}
@Override
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;
}
}
@Override
public int getFieldNumber(String name) { 

Integer number = fieldMap.get(name);
return number == null ? 0 : number;
}
@Override
public boolean isInitialized(User message) { 

return message.getEmail() != null;
}
@Override
public User newMessage() { 

return new User();
}
@Override
public String messageName() { 

return User.class.getSimpleName();
}
@Override
public String messageFullName() { 

return User.class.getName();
}
@Override
public Class<? super User> typeClass() { 

return User.class;
}
@Override
public void mergeFrom(Input input, User message) throws IOException { 

while (true) { 

int number = input.readFieldNumber(this);
switch (number) { 

case 0:
return;
case 1:
message.setEmail(input.readString());
break;
case 2:
message.setFirstName(input.readString());
break;
case 3:
message.setLastName(input.readString());
break;
case 4:
if (message.getFriends() == null)
message.setFriends(new ArrayList<>());
message.getFriends().add(input.mergeObject(null, this));
break;
default:
input.handleUnknownField(number, this);
}
}
}
@Override
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 (user.getFriends() != null) { 

for (User friend : user.getFriends()) { 

if (friend != null)
output.writeObject(4, friend, this, true);
}
}
}
}

序列化和反序列化示例:

package demo;
import demo.domain.User;
import demo.serializing.UserSchema;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import lombok.extern.java.Log;
import java.util.ArrayList;
import java.util.List;
@Log
public class App { 

public static void main(String[] args) { 

User user1 = new User();
user1.setEmail("1178449100@qq.com");
user1.setFirstName("wenwen");
user1.setLastName("zha");
User user2 = new User();
user2.setEmail("gumengqin@qq.com");
List<User> users = new ArrayList<>();
users.add(user2);
user1.setFriends(users);
Schema<User> schema = new UserSchema();
byte[] data;
data = ProtostuffIOUtil.toByteArray(user1, schema, LinkedBuffer.allocate());
log.info("序列化完成:" + data.length);
User newUser = new User();
ProtostuffIOUtil.mergeFrom(data, newUser, schema);
log.info("反序列化完成:" + newUser);
}
}

RuntimeSchema

使用RuntimeSchema可以不用自定义Schema,省了不少工作。

package demo.serializing;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ProtostuffUtils { 

//避免每次序列化都重新申请Buffer空间
private static LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
//缓存Schema
private static Map<Class<?>, Schema<?>> schemaCache = new ConcurrentHashMap<Class<?>, Schema<?>>();
//序列化方法,把指定对象序列化成字节数组
@SuppressWarnings("unchecked")
public static <T> byte[] serialize(T obj) { 

Class<T> clazz = (Class<T>) obj.getClass();
Schema<T> schema = getSchema(clazz);
byte[] data;
try { 

data = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
} finally { 

buffer.clear();
}
return data;
}
//反序列化方法,将字节数组反序列化成指定Class类型
public static <T> T deserialize(byte[] data, Class<T> clazz) { 

Schema<T> schema = getSchema(clazz);
T obj = schema.newMessage();
ProtostuffIOUtil.mergeFrom(data, obj, schema);
return obj;
}
@SuppressWarnings("unchecked")
private static <T> Schema<T> getSchema(Class<T> clazz) { 

Schema<T> schema = (Schema<T>) schemaCache.get(clazz);
if (schema == null) { 

schema = RuntimeSchema.getSchema(clazz);
if (schema != null) { 

schemaCache.put(clazz, schema);
}
}
return schema;
}
}

重新测试:

package demo;
import demo.domain.User;
import demo.serializing.ProtostuffUtils;
import lombok.extern.java.Log;
import java.util.ArrayList;
import java.util.List;
@Log
public class App { 

public static void main(String[] args) { 

User user1 = new User();
user1.setEmail("1178449100@qq.com");
user1.setFirstName("wenwen");
user1.setLastName("zha");
User user2 = new User();
user2.setEmail("gumengqin@qq.com");
List<User> users = new ArrayList<>();
users.add(user2);
user1.setFriends(users);
byte[] data = ProtostuffUtils.serialize(user1);
log.info("序列化完成:" + data.length);
User newUser=ProtostuffUtils.deserialize(data,User.class);
log.info("反序列化完成:" + newUser);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/135575.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • threadlocal底层实现_数据库底层实现原理

    threadlocal底层实现_数据库底层实现原理ThreadLocal作用:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂性。package com.mupack;public class App{ private String content; public void setContent(String content) { this.content = content; } public Stri

  • rabbitmq集群搭建_集群搭建步骤

    rabbitmq集群搭建_集群搭建步骤MQ为什么要使用集群?单机版无法满足真实应用的要求,如果RabbitMQ服务器遇到内存崩溃、机器掉电或者主板故障等情况况,该怎么办?单台RabbitMQ服务器可以满足每秒1000条消息的吞吐量,那么如果应用需要RabbitMQ服务满足每秒10万条消息的吞吐量呢?购买昂贵的服务器来增强单机RabbitMQ务的性能显得不足,此时搭建一个RabbitMQ集群才是解决实际生产中问题的关键。准备环境虚拟机环境:VMware®Workstation16Pro虚拟机版本:16.1.2build-1

  • gamma correction什么意思_伽马校正计算方法

    gamma correction什么意思_伽马校正计算方法伽马是数字成像系统的一个重要特征,它定义了像素值与其实际亮度之间的关系。在标准显示器上面,如果没有伽马,数码相机拍摄到的阴影内容便会跟我们实际看到的有所差异。平时我们所说的伽马校正、伽马编码、伽马压缩,都是伽马曲线的各种应用场景,属于相似的概念。对于伽马工作原理的理解,一方面可以提高摄影者的曝光技术,另一方面可以帮助人们更好地利用后期的图像编辑功能。

  • 单调队列和单调栈详解

    单调队列和单调栈详解这里是我的blog:有更多算法分享=v=https://endlesslethe.com/monotone-queue-and-stack-tutorial.html前言单调栈和单调队列算是栈和队列的高级应用吧,在公司面试中应该是不怎么会出现的(除非算法岗?)。因为原理比较简单,网络上的相关资料反而对于这两个东西说得都不甚清楚,尤其是它们的应用方法。最基本的两本中文算法书“紫书”和“白皮”都

  • Verilog读写文件

    Verilog读写文件一.读写文件相关的系统任务  在进行FPGA模块的开发过程中,常常需要对数据的处理过程进行行为仿真,以验证FPGA的功能逻辑是否正确,因此需要将FPGA行为仿真的结果与MATLAB或C/C++的处理结果进行对比验证。但需要对比的数据量比较大时,将输入输出结果数据存入文件进行对比是非常常用的方法。  Verilog中读写文件常用到的系统任务主要有以下几个:1.文件打开、关闭与定位操作:$fo…

  • python fileinput_python模块fileinput

    python fileinput_python模块fileinput在python脚本语言中的fileinput模块可以对一个或多个文件的内容进行迭代,编历操作.常用的函数:fileinput.input()#读取文件的内容fileinput.filename()#文件的名称fileinput.lineno()#当前读取行的数量fileinput.filelineno()#读取行的行号fileinput.isfir…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号