前言:由于搜集网络,发现Protostuff相关内容较少,故此发布这篇文章

1. 何为序列化

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

序列化使其他代码可以查看或修改那些不序列化便无法访问的对象实例数据。确切地说,代码执行序列化需要特殊的权限:即指定了 SerializationFormatter 标志的 SecurityPermission。在默认策略下,通过 Internet 下载的代码或 Internet 代码不会授予该权限;只有本地计算机上的代码才被授予该权限。

通常,对象实例的所有字段都会被序列化,这意味着数据会被表示为实例的序列化数据。这样,能够解释该格式的代码有可能能够确定这些数据的值,而不依赖于该成员的可访问性。类似地,反序列化从序列化的表示形式中提取数据,并直接设置对象状态,这也与可访问性规则无关。

对于任何可能包含重要的安全性数据的对象,如果可能,应该使该对象不可序列化。如果它必须为可序列化的,请尝试生成特定字段来保存不可序列化的重要数据。如果无法实现这一点,则应注意该数据会被公开给任何拥有序列化权限的代码,并确保不让任何恶意代码获得该权限。

2. 常见的序列化有哪些

Xml、Json、JDK传统序列化、Protobuf序列化  (随口举例,笔者也懒得去收集了)

3. 序列化体积对比

理论分析结论:Xml >或 Json > Protobuf

其中在某些特殊场景下,Json可能大于Jdk,Xml可能大于或小于Jdk。

原理分析:传统的Xml序列化,以字段名开头,字段名结尾,存在一个字段冗余,在某些特定的级别格式下,Xml报文长度过量冗余。

:Json序列化,某些Json序列化可能将空字段也序列化出来,如:{“user”:”null”},在过滤空的场景下,Json序列化内容比Jdk传统序列化体积小

:Jdk传统序列化,即实现Serializable接口的对象或数据模型转化为Byte数组,内容包含类信息、字段信息等,故此体积较大

:Protobuf序列化,讲对象或数据模型中有效的内容转化成Byte数组,不包括类信息与数据模型,再反序列化时需要指定目标数据结构,根据数据结构类型对应反序列化,由于仅仅包含内容,故此体积最小

4. 序列效率对比

根据第3点理论原理分析我们不难看出来,xml和json实际效率相差不多,可能就在于xml稍多的内容读写,故此xml效率低于json

由于json序列化和反序列化是完全基于反射,故此,json效率低于Jdk原生序列化

Jdk原生序列化属于基于半反射完成,效率高于Json

而Protobuf,相比jdk原生序列化来说,少做了很多事情,故此Protobuf效率较jdk原生序列化高出很多(排除谷歌对Protobuf的特定算法带来的优势)。

5. 图标分析

笔者并非传说中的那么蛋疼,故此在网络收集相关评测结果。

6. 在JAVA中如何使用

maven引入:

com.dyuproject.protostuff

protostuff-core

1.0.12

com.dyuproject.protostuff

protostuff-runtime

1.0.12

工具类:

package com.protobuf.util;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.Serializable;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.Collection;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

import com.dyuproject.protostuff.LinkedBuffer;

import com.dyuproject.protostuff.ProtostuffIOUtil;

import com.dyuproject.protostuff.Schema;

import com.dyuproject.protostuff.runtime.RuntimeSchema;

@SuppressWarnings("unchecked")

public class ProtobufUtil {

private static Map, Schema>> cachedSchema = new ConcurrentHashMap, Schema>>();

private static Map, Field> wrapperMap = new ConcurrentHashMap, Field>();

private static Map, Object> unWrapperMap = new ConcurrentHashMap, Object>();

private static Schema getSchema(Class cls) {

Schema schema = (Schema) cachedSchema.get(cls);

if (schema == null) {

schema = RuntimeSchema.createFrom(cls);

if (schema != null) {

cachedSchema.put(cls, schema);

}

}

return schema;

}

/**

* 序列化

*

* @param obj

* @return

*/

public static byte[] serialize(T obj) {

if (isNullOrEmpty(obj)) {

return null;

}

try {

if(List.class.isAssignableFrom(obj.getClass())){

List list=(List)obj;

Class> clazz=list.get(0).getClass();

byte [] data=serializeList(list);

CustomWrapper wrapper=new CustomWrapper(clazz,data);

return serializeT(wrapper);

}

if(Set.class.isAssignableFrom(obj.getClass())){

List list=new ArrayList((Set)obj);

Class> clazz=list.get(0).getClass();

byte [] data=serializeList(list);

CustomWrapper wrapper=new CustomWrapper(clazz,data);

return serializeT(wrapper);

}

if(ValueWrapper.isSpecialType(obj.getClass())){

ValueWrapper wrapper=new ValueWrapper(obj);

return serializeT(wrapper);

}

return serializeT(obj);

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

public static byte[] serializeList(List objList) {

if (objList == null || objList.isEmpty()) {

throw new RuntimeException("序列化对象列表(" + objList + ")参数异常!");

}

Schema schema = (Schema) RuntimeSchema.getSchema(objList.get(0).getClass());

LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);

byte[] protostuff = null;

ByteArrayOutputStream bos = null;

try {

bos = new ByteArrayOutputStream();

ProtostuffIOUtil.writeListTo(bos, objList, schema, buffer);

protostuff = bos.toByteArray();

} catch (Exception e) {

throw new RuntimeException("序列化对象列表(" + objList + ")发生异常!", e);

} finally {

buffer.clear();

try {

if(bos!=null){

bos.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

return protostuff;

}

private static byte[] serializeT(T obj) {

Class cls = (Class) obj.getClass();

LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.MIN_BUFFER_SIZE);

try {

Schema schema = getSchema(cls);

return ProtostuffIOUtil.toByteArray(obj, schema, buffer);

} catch (Exception e) {

throw new IllegalStateException(e.getMessage(), e);

} finally {

buffer.clear();

}

}

/**

* 反序列化

*

* @param data

* @param cls

* @return

*/

public static T unSerialize(byte[] data,Class> clazz) {

if (isNullOrEmpty(data)) {

return null;

}

try {

if(List.class.isAssignableFrom(clazz)){

CustomWrapper wrapper= unSerializeT(data, CustomWrapper.class);

return (T) unSerializeList(data, wrapper.getClazz());

}

if(Set.class.isAssignableFrom(clazz)){

CustomWrapper wrapper= unSerializeT(data, CustomWrapper.class);

return (T) unSerializeSet(data, wrapper.getClazz());

}

if(ValueWrapper.isSpecialType(clazz)){

ValueWrapper wrapper= unSerializeT(data, ValueWrapper.class);

if(wrapper==null||isNullOrEmpty(wrapper)){

return null;

}

return wrapper.getValue();

}

return (T) unSerializeT(data, clazz);

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

public static Set unSerializeSet(byte[] data, Class clazz) {

if (data == null || data.length == 0) {

throw new RuntimeException("反序列化对象发生异常,byte序列为空!");

}

Schema schema = RuntimeSchema.getSchema(clazz);

try {

List list = ProtostuffIOUtil.parseListFrom(new ByteArrayInputStream(data), schema);

return new HashSet(list);

} catch (IOException e) {

throw new RuntimeException("反序列化对象列表发生异常!",e);

}

}

public static List unSerializeList(byte[] data, Class clazz) {

if (data == null || data.length == 0) {

throw new RuntimeException("反序列化对象发生异常,byte序列为空!");

}

Schema schema = RuntimeSchema.getSchema(clazz);

List result = null;

try {

result = ProtostuffIOUtil.parseListFrom(new ByteArrayInputStream(data), schema);

} catch (IOException e) {

throw new RuntimeException("反序列化对象列表发生异常!",e);

}

return result;

}

private static T unSerializeT(byte[] data, Class cls) {

try {

T message = cls.newInstance();

Schema schema = getSchema(cls);

ProtostuffIOUtil.mergeFrom(data, message, schema);

return message;

} catch (Exception e) {

throw new IllegalStateException(e.getMessage(), e);

}

}

public static boolean isNullOrEmpty(Object obj) {

try {

if (obj == null)

return true;

if (obj instanceof CharSequence) {

return ((CharSequence) obj).length() == 0;

}

if (obj instanceof Collection) {

return ((Collection>) obj).isEmpty();

}

if (obj instanceof Map) {

return ((Map, ?>) obj).isEmpty();

}

if (obj instanceof Object[]) {

Object[] object = (Object[]) obj;

if (object.length == 0) {

return true;

}

boolean empty = true;

for (int i = 0; i < object.length; i++) {

if (!isNullOrEmpty(object[i])) {

empty = false;

break;

}

}

return empty;

}

return false;

} catch (Exception e) {

e.printStackTrace();

return true;

}

}

@SuppressWarnings({ "serial" })

public static class CustomWrapper implements Serializable{

private Class> clazz;

private byte []data;

public CustomWrapper(){}

public CustomWrapper(Class> clazz,byte[] data){

this.clazz=clazz;

this.data=data;

}

public byte[] getData() {

return data;

}

public void setData(byte[] data) {

this.data = data;

}

public Class> getClazz() {

return clazz;

}

public void setClazz(Class> clazz) {

this.clazz = clazz;

}

}

@SuppressWarnings({ "rawtypes", "serial", "unused" })

public static class ValueWrapper implements Serializable{

private Map mapValue;

private List listValue;

private Collection collectionValue;

private Iterable iterableValue;

private Set setValue;

private String stringValue;

private Byte byteValue;

private Short shortValue;

private Long longValue;

private Integer integerValue;

private Double doubleValue;

private Float floatValue;

private Character characterValue;

private Boolean booleanValue;

public ValueWrapper(){}

public ValueWrapper(Object data) throws IllegalArgumentException, IllegalAccessException {

if (data == null) {

return;

}

if (isNullOrEmpty(wrapperMap)) {

initFiledType();

}

if (wrapperMap.containsKey(data.getClass())) {

Field f = wrapperMap.get(data.getClass());

f.setAccessible(true);

f.set(this, data);

}

for (Class> clazz : wrapperMap.keySet()) {

if (!clazz.isAssignableFrom(data.getClass())) {

continue;

}

Field f = wrapperMap.get(clazz);

f.setAccessible(true);

f.set(this, data);

wrapperMap.put(data.getClass(), f);

return;

}

}

public static boolean isSpecialType(Class> clazz){

if (isNullOrEmpty(wrapperMap)) {

initFiledType();

}

if(unWrapperMap.containsKey(clazz)){

return false;

}

if(wrapperMap.containsKey(clazz)){

return true;

}

for (Class> clazzTmp : wrapperMap.keySet()) {

if (!clazzTmp.isAssignableFrom(clazz)) {

continue;

}

Field f = wrapperMap.get(clazzTmp);

f.setAccessible(true);

wrapperMap.put(clazz, f);

return true;

}

unWrapperMap.put(clazz, clazz);

return false;

}

private static void initFiledType() {

Field[] fields = ValueWrapper.class.getDeclaredFields();

for (Field f : fields) {

wrapperMap.put(f.getType(), f);

}

}

public T getValue() throws IllegalArgumentException, IllegalAccessException {

for (Class> clazz : wrapperMap.keySet()) {

T result = (T) wrapperMap.get(clazz).get(this);

if (isNullOrEmpty(result)) {

continue;

}

return result;

}

return null;

}

}

}

测试图:

protostuff java_Protostuff一键序列化工具、Protobuf JAVA实现相关推荐

  1. Redis+protostuff 实现对象序列化保存,反序列化获取

    很多情况我们为了解决并发问题使用redis非关系型数据库保存数据,我们序列化保存方便数据的传输可以随时把对象持久化到数据库.文件等系统里,也方我们反序列化获取对象,下面我就开始整理吧 1.利用mave ...

  2. java序列化工具 protoStuff的使用

    1.前言 在互联网快速发展的今天,互联网架构也在不断的升级.而数据的传输和存贮是互联网系统中不可或缺的一部分.举个简单的例子,目前微服务已经很普及了,就拿dubbo来说,不管用jdk自带的序列化,还是 ...

  3. 浅析若干Java序列化工具

    在java中socket传输数据时,数据类型往往比较难选择.可能要考虑带宽.跨语言.版本的兼容等问题. 比较常见的做法有:1. 采用java对象的序列化和反序列化2. 把对象包装成JSON字符串传输3 ...

  4. jackson、fastjson、kryo、protostuff等序列化工具性能对比

    简介 实际项目中,我们经常需要使用序列化工具来存储和传输对象.目前用得比较多的序列化工具有:jackson.fastjson.kryo.protostuff.fst 等,本文将简单对比这几款工具序列化 ...

  5. java protostuff 好处_Java 序列化框架性能对比(kryo、hessian、java、protostuff)

    简介: 优点 缺点 Kryo 速度快,序列化后体积小 跨语言支持较复杂 Hessian 默认支持跨语言 较慢 Protostuff 速度快,基于protobuf 需静态编译 Protostuff-Ru ...

  6. 【java】序列化:ProtoBuf 与 JSON 的比较

    1.概述 转载:序列化:ProtoBuf 与 JSON 的比较! 介绍 ProtoBuf 是google团队开发的用于高效存储和读取结构化数据的工具.什么是结构化数据呢,正如字面上表达的,就是带有一定 ...

  7. .NET序列化工具Jil、Json.NET和Protobuf的简单测评

    前一段时间逛园子的时候发现有人比较了Jil.Json.NET和Protobuf的性能,一时好奇,也做了个测试,这里记录下来,以供查阅. 前期准备 依赖类库的话,可以通过Nuget在公共组件库总下载,这 ...

  8. Java序列化工具的对比

    在Java开发工具当中,Java序列化工具是比较常用的,而且种类也有不少,下面小编就来做个对比: 1.Java序列化工具的技术原理对比 Binary Formats & language-sp ...

  9. protostuff java_Protostuff序列化和反序列化的使用说明

    大家都知道protobuf好用,可是在网上找到的netty整合protobuf的文章都是千篇一律,自己编写proto文件然后使用工具转java文件用起来复杂麻烦,经过不懈努力终于找到了一个简单的方法希 ...

最新文章

  1. 注解方式实现aop-快速入门
  2. 重学java基础第四课:关于教育和对大家的期望
  3. 游标声明 oracle,Oracle游标声明
  4. 5006.c++类中使用static变量bug
  5. php案例纠错,PHP编程纠错指南
  6. BitCoin Gloom系列
  7. sublime text多文件夹查找关键字
  8. 【原生JS】web原生文字轮播效果
  9. 18. 避免使用vectorbool
  10. cni k8s 插件安装_实现K8S中Pod带宽限制
  11. Linux nohup 关闭终端的时候,程序依然能在后台运行( linux重定向及nohup不输出的方法)...
  12. 2019版PHP自动发卡平台源码
  13. android音频切换到蓝牙耳机,在Android上将音频路由到蓝牙耳机(非A2DP)
  14. linux系统安装文网卫士,360主机卫士 linux版的安装/使用/卸载 方法
  15. 一个c语言程序多个源文件,链接多个C源文件
  16. 【蓝桥杯备战】 Day02
  17. Galaxian 小蜜蜂
  18. java造成capturing lambda后需要注意的事情
  19. 微信点餐系统html,SpringBoot实战——微信点餐系统(示例代码)
  20. 什么是pv和uv? pv、uv

热门文章

  1. 为什么使用基于KVM的VPS服务器?
  2. windows无法枚举容器内对象 访问被拒绝
  3. OSSEC搭建部署(ossec-server(CentOS7.X)和ossec-agent(CentOS7.X))
  4. 花些时间把python入门——python、vscode、廖雪峰
  5. 基于ARM核心板的电力边缘物联代理系统方案
  6. 用企业版证书,发布in house app
  7. 数据分析领域,为什么要对比Excel学习Python?
  8. SPSS调查问卷缺失值或无效数据如何判断和替换?
  9. 腾讯游戏学院专家:UE高级性能剖析技术之RHI
  10. java,jdk 分不清,是否免费,怎么选择合适的版本