后期将会尝试使用Protostuff进行序列化
一、Jdk与Hessian2的序列化的对比
Hessian在体积和速度上相较于JDK序列化更优秀,且由于Hessian设计之初就考虑到跨语言的需求因此在兼容性方面也更胜一筹。
1.Hessian2报文
使用hessian完成序列化所传输的字节数
2. JDK报文
使用JDK完成序列化所传输的字节数
总结:对比之下Hessian2相比于jdk报文字节节省了40%左右,在报文上体现的更加明显,jdk的报文一个屏幕根本截不下来,而且Hessian2的跨语言性更强,速度更快
二、代码
我是通过序列化工厂的方式来方便序列化方式的改变
具体代码请查看gitee:rengerpc: rrpc远程方法调用框架开发
序列化工厂
*
* 简单序列化工厂
*/
public class SerializerFactory {
//创建序列化缓存
public final static Map<String,SerializerWrapper> SERIALIZER_CACHE = new ConcurrentHashMap<>();
public final static Map<Byte,SerializerWrapper> SERIALIZER_CACHE_CODE = new ConcurrentHashMap<>();
static {
SerializerWrapper jdk = new SerializerWrapper((byte) 1, "jdk", new JdkSerializer());
SerializerWrapper json = new SerializerWrapper((byte) 2, "json", new JsonSerializer());
SerializerWrapper hessian = new SerializerWrapper((byte) 3, "hessian", new HessianSerializer());
SERIALIZER_CACHE.put("jdk",jdk);
SERIALIZER_CACHE.put("json",json);
SERIALIZER_CACHE.put("hessian",hessian);
SERIALIZER_CACHE_CODE.put((byte) 1,jdk);
SERIALIZER_CACHE_CODE.put((byte) 2,json);
SERIALIZER_CACHE_CODE.put((byte) 3,hessian);
}
/**
* 使用工厂方法获取serializerWrapper
* @param serializeType
* @return
*/
public static SerializerWrapper getSerializer(String serializeType) {
return SERIALIZER_CACHE.get(serializeType);
}
public static SerializerWrapper getSerializer(byte serializeCode) {
return SERIALIZER_CACHE_CODE.get(serializeCode);
}
}
Hessian2
* 使用hessian2进行序列化
*/
@Slf4j
public class HessianSerializer implements Serializer {
@Override
public byte[] serialize(Object object) {
if (object == null) {
return null;
}
try ( //对象 --- 》 字节数组 序列化和压缩
//流的定义写在这,会自动关闭,不需要finally
ByteArrayOutputStream baos = new ByteArrayOutputStream();
) {
Hessian2Output hessian2Output = new Hessian2Output(baos);
hessian2Output.writeObject(object);
hessian2Output.flush();
/* ObjectOutputStream outputStream = new ObjectOutputStream(baos)
outputStream.writeObject(object);*/
byte[] result = baos.toByteArray();
if (log.isDebugEnabled()) {
log.debug("对象使用hessian【{}】已经完成了序列化操作,字节数为【{}】", object,result.length);
}
return result;
} catch (IOException e) {
log.error("使用hessian序列化对象【{}】时发生异常", object);
throw new SerializeExcecption(e);
}
}
@Override
public <T> T deserialize(byte[] bytes, Class<T> clazz) {
if (bytes == null || clazz == null) {
return null;
}
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
) {
/*ObjectInputStream objectInputStream = new ObjectInputStream(bais)
Object object = objectInputStream.readObject();*/
Hessian2Input hessian2Input = new Hessian2Input(bais);
T t = (T) hessian2Input.readObject();
if (log.isDebugEnabled()) {
log.debug("类【{}】使用hessian已经完成了反序列化操作", clazz);
}
return t;
} catch (IOException e) {
log.error("使用hessian反序列化对象【{}】时发生异常", clazz);
throw new SerializeExcecption(e);
}
}
}
JDK
@Slf4j
public class JdkSerializer implements Serializer {
@Override
public byte[] serialize(Object object) {
if (object == null) {
return null;
}
try ( //对象 --- 》 字节数组 序列化和压缩
//流的定义写在这,会自动关闭,不需要finally
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(baos)
) {
outputStream.writeObject(object);
byte[] result = baos.toByteArray();
if (log.isDebugEnabled()){
log.debug("对象【{}】已经完成了序列化操作,字节数为【{}】",object,result.length);
}
return result;
} catch (IOException e) {
log.error("序列化对象【{}】时发生异常",object);
throw new SerializeExcecption(e);
}
}
@Override
public <T> T deserialize(byte[] bytes, Class<T> clazz) {
if (bytes == null || clazz == null){
return null;
}
try( ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream objectInputStream= new ObjectInputStream(bais)
) {
Object object = objectInputStream.readObject();
if (log.isDebugEnabled()){
log.debug("类【{}】已经完成了反序列化操作",clazz);
}
return (T) object;
} catch (IOException | ClassNotFoundException e) {
log.error("反序列化对象【{}】时发生异常",clazz);
throw new SerializeExcecption(e);
}
}
}