简介:
Protostuff是谷歌产品,用于高效处理对象的序列化和方序列化
那这个Schema是什么呢?就是一个组织结构,就好比是数据库中的表、视图等等这样的组织机构,在这里表示的就是序列化对象的结构
pom坐标:
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.6.0</version>
</dependency>
proStuff工具类
序列化方法,里面的代码很容易理解,首先获得要序列化对象的类,然后为其分配一个缓存空间,其次获得这个类的Schema。最后一行代码ProtostuffIOUtil.toByteArray进行序列化
反序列里面的代码更简单了,首先根据序列化对象获取其组织结构Schema。然后根据byte直接mergeFrom成一个对象
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;
}
}
案例运用:在上下问中获取运用后台登录用户信息
@Component
@Slf4j
@Order(-1)
@ConditionalOnBean(RedisCacheStorage.class)
public class NewSessionContextFilter{
// 定义schema
private static final RuntimeSchema<OperationBO> SCHEMA = RuntimeSchema.createFrom(OperationBO.class);
// 获取数据,反序列化
private void yopContext(HttpServletRequest request){
Cookie[] cookies = request.getCookies();
if (!Util.isEmpty(cookies)) {
String sessionId = "";
Cookie[] var4 = cookies;
int var5 = cookies.length;
for (int var6 = 0; var6 < var5; ++var6) {
Cookie cookie = var4[var6];
if (cookie.getName().equals("SESSIONID")) {
sessionId = new String(Base64.getDecoder().decode(cookie.getValue()));
}
}
byte[] adminBytes = this.redisCacheStorage.get(sessionId.getBytes());
OperationBO operationBO = null;
log.info("SessionContextFilter:{}",new String(adminBytes== null ? new byte[]{} : adminBytes));
if (!Util.isEmpty(adminBytes)) {
operationBO = SCHEMA.newMessage();
ProtostuffIOUtil.mergeFrom(adminBytes, adminUserContext, SCHEMA);
ContextHolder.setContext(AdminUserContext.convert(operationBO));
}
}
}
保存获取的用户信息:
public class ContextHolder {
private static final ThreadLocal<OperationBO> contextHolder = new ThreadLocal<OperationBO>() {
/**
*
* 默认数据
*/
@Override
protected OperationBO initialValue(){
return new OperationBO(0L,"admin");
}
};
/**
* 切换数据源
* @param key
*/
public static void setContext(OperationBO key) {
contextHolder.set(key);
}
/**
* 获取数据源
* @return
*/
public static OperationBO getContext() {
return contextHolder.get();
}
/**
* 重置数据源
*/
public static void clearContext() {
contextHolder.remove();
}
}
实体类:
@Data
public class OperationBO implements Serializable {
// 登录人id
private Long operationId;
// 登录人姓名
private String operationName;
}
业务代码中直接获取,不再需要没次从参数中传入:
OperationBO operationBO = ContextHolder.getContext();