提交 1c281102 编写于 作者: 武汉红喜's avatar 武汉红喜

serialization

上级 d54a3061
package org.hongxi.whatsmars.common;
import java.util.regex.Pattern;
/**
* Created on 2019/8/5.
*
* @author shenhongxi
*/
public class Constants {
public static final String COMMA_SEPARATOR = ",";
public static final Pattern COMMA_SPLIT_PATTERN = Pattern.compile("\\s*[,]+\\s*");
public static final String PROTOCOL_SEPARATOR = "://";
public static final String PATH_SEPARATOR = "/";
}
......@@ -19,6 +19,30 @@
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.6.12</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>2.57</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>4.0.2</version>
</dependency>
</dependencies>
......
package org.hongxi.whatsmars.common.serialize;
import org.nustaq.serialization.FSTConfiguration;
import java.io.IOException;
/**
* Created on 2019/8/5.
*
* @author shenhongxi
*/
public class FSTSerialization implements Serialization {
private FSTConfiguration fst = FSTConfiguration.createStructConfiguration();
@Override
public byte[] serialize(Object obj) throws IOException {
return fst.asByteArray(obj);
}
@Override
public <T> T deserialize(byte[] bytes, Class<T> clz) throws IOException, ClassNotFoundException {
return (T) fst.asObject(bytes);
}
@Override
public byte[] serializeMulti(Object[] data) throws IOException {
return serialize(data);
}
@Override
public Object[] deserializeMulti(byte[] data, Class<?>[] classes) throws IOException, ClassNotFoundException {
return null;
}
@Override
public int getSerializationNumber() {
return 5;
}
}
package org.hongxi.whatsmars.common.serialize;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
/**
* fastjson 序列化
*
* <pre>
* 对于嵌套场景无法支持
* </pre>
*
*/
public class FastJsonSerialization implements Serialization {
private final static Charset CHARSET_UTF8 = Charset.forName("UTF-8");
@Override
public byte[] serialize(Object obj) throws IOException {
SerializeWriter out = new SerializeWriter();
JSONSerializer serializer = new JSONSerializer(out);
serializer.config(SerializerFeature.WriteEnumUsingToString, true);
serializer.config(SerializerFeature.WriteClassName, true);
serializer.write(obj);
return out.toBytes(CHARSET_UTF8);
}
@Override
public <T> T deserialize(byte[] bytes, Class<T> clz) throws IOException {
return JSON.parseObject(new String(bytes, CHARSET_UTF8), clz);
}
@Override
public byte[] serializeMulti(Object[] data) throws IOException {
return serialize(data);
}
@Override
public Object[] deserializeMulti(byte[] data, Class<?>[] classes) throws IOException {
List<Object> list = JSON.parseArray(new String(data), classes);
if (list != null) {
return list.toArray();
}
return null;
}
@Override
public int getSerializationNumber() {
return 2;
}
}
package org.hongxi.whatsmars.common.serialize.hessian2;
package org.hongxi.whatsmars.common.serialize;
import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import org.hongxi.whatsmars.common.serialize.Serialization;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
......@@ -11,21 +10,21 @@ import java.io.IOException;
/**
* Created by shenhongxi on 2018/10/7.
*/
public class Hessian2Serialization implements Serialization {
public class HessianSerialization implements Serialization {
@Override
public byte[] serialize(Object data) throws IOException {
public byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Hessian2Output out = new Hessian2Output(bos);
out.writeObject(data);
out.writeObject(obj);
out.flush();
return bos.toByteArray();
}
@SuppressWarnings("unchecked")
@Override
public <T> T deserialize(byte[] data, Class<T> clz) throws IOException {
Hessian2Input input = new Hessian2Input(new ByteArrayInputStream(data));
public <T> T deserialize(byte[] bytes, Class<T> clz) throws IOException {
Hessian2Input input = new Hessian2Input(new ByteArrayInputStream(bytes));
return (T) input.readObject(clz);
}
......
package org.hongxi.whatsmars.common.serialize;
import java.io.*;
/**
* Created on 2019/8/5.
*
* @author shenhongxi
*/
public class JavaSerialization implements Serialization {
@Override
public byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
return baos.toByteArray();
}
@Override
public <T> T deserialize(byte[] bytes, Class<T> clz) throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return (T) ois.readObject();
}
@Override
public byte[] serializeMulti(Object[] data) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
for (Object obj : data) {
oos.writeObject(obj);
}
return baos.toByteArray();
}
@Override
public Object[] deserializeMulti(byte[] data, Class<?>[] classes) throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bais);
Object[] objects = new Object[classes.length];
for (int i = 0; i < classes.length; i++) {
objects[i] = ois.readObject();
}
return objects;
}
@Override
public int getSerializationNumber() {
return 1;
}
}
package org.hongxi.whatsmars.common.serialize;
import org.msgpack.MessagePack;
import javax.naming.OperationNotSupportedException;
import java.io.IOException;
/**
* Created on 2019/8/5.
*
* @author shenhongxi
*/
public class MsgpackSerialization implements Serialization {
private MessagePack messagePack = new MessagePack();
@Override
public byte[] serialize(Object obj) throws IOException {
return messagePack.write(obj);
}
@Override
public <T> T deserialize(byte[] bytes, Class<T> clz) throws IOException, ClassNotFoundException {
return messagePack.read(bytes, clz);
}
@Override
public byte[] serializeMulti(Object[] data) throws IOException {
return serialize(data);
}
@Override
public Object[] deserializeMulti(byte[] data, Class<?>[] classes) {
return null;
}
@Override
public int getSerializationNumber() {
return 3;
}
}
package org.hongxi.whatsmars.common.serialize;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.MessageLite;
import java.io.*;
import java.lang.reflect.Method;
/**
* protobuf序列化器,支持基本数据类型及其包装类、String、Throwable、Protobuf2/3对象
*
*/
public class ProtobufSerialization implements Serialization {
@Override
public byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
// 对throwable使用 java ObjectOutputStream进行序列化
if (Throwable.class.isAssignableFrom(obj.getClass())) {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.flush();
} else {
CodedOutputStream output = CodedOutputStream.newInstance(baos);
serialize(output, obj);
output.flush();
}
return baos.toByteArray();
}
@SuppressWarnings("unchecked")
@Override
public <T> T deserialize(byte[] bytes, Class<T> clz) throws IOException, ClassNotFoundException {
// 对throwable使用 java ObjectInputStream进行反序列化
if (Throwable.class.isAssignableFrom(clz)) {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
return (T) ois.readObject();
} else {
CodedInputStream in = CodedInputStream.newInstance(bytes);
return (T) deserialize(in, clz);
}
}
@Override
public byte[] serializeMulti(Object[] data) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
CodedOutputStream output = CodedOutputStream.newInstance(baos);
for (Object obj : data) {
serialize(output, obj);
}
output.flush();
return baos.toByteArray();
}
@Override
public Object[] deserializeMulti(byte[] data, Class<?>[] classes) throws IOException {
CodedInputStream in = CodedInputStream.newInstance(data);
Object[] objects = new Object[classes.length];
for (int i = 0; i < classes.length; i++) {
objects[i] = deserialize(in, classes[i]);
}
return objects;
}
protected void serialize(CodedOutputStream output, Object obj) throws IOException {
if (obj == null) {
output.writeBoolNoTag(true);
} else {
output.writeBoolNoTag(false);
Class<?> clazz = obj.getClass();
if (clazz == int.class || clazz == Integer.class) {
output.writeSInt32NoTag((Integer) obj);
} else if (clazz == long.class || clazz == Long.class) {
output.writeSInt64NoTag((Long) obj);
} else if (clazz == boolean.class || clazz == Boolean.class) {
output.writeBoolNoTag((Boolean) obj);
} else if (clazz == byte.class || clazz == Byte.class) {
output.writeRawByte((Byte) obj);
} else if (clazz == char.class || clazz == Character.class) {
output.writeSInt32NoTag((Character) obj);
} else if (clazz == short.class || clazz == Short.class) {
output.writeSInt32NoTag((Short) obj);
} else if (clazz == double.class || clazz == Double.class) {
output.writeDoubleNoTag((Double) obj);
} else if (clazz == float.class || clazz == Float.class) {
output.writeFloatNoTag((Float) obj);
} else if (clazz == String.class) {
output.writeStringNoTag(obj.toString());
} else if (MessageLite.class.isAssignableFrom(clazz)) {
output.writeMessageNoTag((MessageLite) obj);
} else {
throw new IllegalArgumentException("can't serialize " + clazz);
}
}
}
protected Object deserialize(CodedInputStream in, Class<?> clazz) throws IOException {
if (in.readBool()) {
return null;
} else {
Object value;
if (clazz == int.class || clazz == Integer.class) {
value = in.readSInt32();
} else if (clazz == long.class || clazz == Long.class) {
value = in.readSInt64();
} else if (clazz == boolean.class || clazz == Boolean.class) {
value = in.readBool();
} else if (clazz == byte.class || clazz == Byte.class) {
value = in.readRawByte();
} else if (clazz == char.class || clazz == Character.class) {
value = (char) in.readSInt32();
} else if (clazz == short.class || clazz == Short.class) {
value = (short) in.readSInt32();
} else if (clazz == double.class || clazz == Double.class) {
value = in.readDouble();
} else if (clazz == float.class || clazz == Float.class) {
value = in.readFloat();
} else if (clazz == String.class) {
value = in.readString();
} else if (MessageLite.class.isAssignableFrom(clazz)) {
try {
Method method = clazz.getDeclaredMethod("newBuilder", null);
MessageLite.Builder builder = (MessageLite.Builder) method.invoke(null, null);
in.readMessage(builder, null);
value = builder.build();
} catch (Exception e) {
// 这里应该抛出自定义异常
throw new IOException(e);
}
} else {
throw new IllegalArgumentException("can't serialize " + clazz);
}
return value;
}
}
@Override
public int getSerializationNumber() {
return 4;
}
}
......@@ -9,11 +9,11 @@ public interface Serialization {
byte[] serialize(Object obj) throws IOException;
<T> T deserialize(byte[] bytes, Class<T> clz) throws IOException;
<T> T deserialize(byte[] bytes, Class<T> clz) throws IOException, ClassNotFoundException;
byte[] serializeMulti(Object[] data) throws IOException;
Object[] deserializeMulti(byte[] data, Class<?>[] classes) throws IOException;
Object[] deserializeMulti(byte[] data, Class<?>[] classes) throws IOException, ClassNotFoundException;
/**
* serializaion的唯一编号,用于传输协议中指定序列化方式。每种序列化的编号必须唯一。
......
package org.hongxi.whatsmars.common.serialize.hessian2;
import org.hongxi.whatsmars.common.serialize.Serialization;
import java.io.IOException;
/**
* Created by shenhongxi on 2018/10/7.
*/
public class DeserializableObject {
private Serialization serialization;
private byte[] objBytes;
public DeserializableObject(Serialization serialization, byte[] objBytes) {
this.serialization = serialization;
this.objBytes = objBytes;
}
public <T> T deserialize(Class<T> clz) throws IOException {
return serialization.deserialize(objBytes, clz);
}
public Object[] deserializeMulti(Class<?>[] paramTypes) throws IOException {
Object[] ret = null;
if (paramTypes != null && paramTypes.length > 0) {
ret = serialization.deserializeMulti(objBytes, paramTypes);
}
return ret;
}
}
package org.hongxi.whatsmars.common.serialize;
import org.junit.Test;
/**
* Created on 2019/8/5.
*
* @author shenhongxi
*/
public class SerializationTest {
@Test
public void testHessian() throws Exception {
Serialization serialization = new HessianSerialization();
User user = new User("hongxi", 30);
byte[] bytes = serialization.serialize(user);
user = serialization.deserialize(bytes, User.class);
assert "hongxi".equals(user.name) && user.age == 30;
}
@Test
public void testJava() throws Exception {
Serialization serialization = new JavaSerialization();
User user = new User("hongxi", 30);
byte[] bytes = serialization.serialize(user);
user = serialization.deserialize(bytes, User.class);
assert "hongxi".equals(user.name) && user.age == 30;
}
@Test
public void testJson() throws Exception {
Serialization serialization = new FastJsonSerialization();
User user = new User("hongxi", 30);
byte[] bytes = serialization.serialize(user);
user = serialization.deserialize(bytes, User.class);
assert "hongxi".equals(user.name) && user.age == 30;
}
@Test
public void testMsgpack() throws Exception {
Serialization serialization = new MsgpackSerialization();
User user = new User("hongxi", 30);
byte[] bytes = serialization.serialize(user);
user = serialization.deserialize(bytes, User.class);
assert "hongxi".equals(user.name) && user.age == 30;
}
@Test
public void testProtobuf() throws Exception {
Serialization serialization = new ProtobufSerialization();
// 9种基本类型之外的其他类型必须实现 MessageLite 接口
Integer data = 1;
byte[] bytes = serialization.serialize(data);
data = serialization.deserialize(bytes, Integer.class);
assert data == 1;
}
@Test
public void testFST() throws Exception {
Serialization serialization = new FSTSerialization();
User user = new User("hongxi", 30);
byte[] bytes = serialization.serialize(user);
user = serialization.deserialize(bytes, User.class);
assert "hongxi".equals(user.name) && user.age == 30;
}
@Test
public void testHessianMulti() throws Exception {
Serialization serialization = new HessianSerialization();
User user = new User("hongxi", 30);
Object[] data = new Object[]{user, 123, "xxx", false};
byte[] bytes = serialization.serializeMulti(data);
Class[] classes = new Class[data.length];
for (int i = 0; i < data.length; i++) {
classes[i] = data[i].getClass();
}
data = serialization.deserializeMulti(bytes, classes);
assert data.length == 4 && data[2].toString().equals("xxx");
}
@Test
public void testJavaMulti() throws Exception {
Serialization serialization = new JavaSerialization();
User user = new User("hongxi", 30);
Object[] data = new Object[]{user, 123, "xxx", false};
byte[] bytes = serialization.serializeMulti(data);
Class[] classes = new Class[data.length];
for (int i = 0; i < data.length; i++) {
classes[i] = data[i].getClass();
}
data = serialization.deserializeMulti(bytes, classes);
assert data.length == 4 && data[2].toString().equals("xxx");
}
@Test
public void testJsonMulti() throws Exception {
Serialization serialization = new FastJsonSerialization();
User user = new User("hongxi", 30);
Object[] data = new Object[]{user, 123, "xxx", false};
byte[] bytes = serialization.serializeMulti(data);
Class[] classes = new Class[data.length];
for (int i = 0; i < data.length; i++) {
classes[i] = data[i].getClass();
}
data = serialization.deserializeMulti(bytes, classes);
assert data.length == 4 && data[2].toString().equals("xxx");
}
@Test
public void testProtobufMulti() throws Exception {
Serialization serialization = new ProtobufSerialization();
Object[] data = new Object[]{9999L, 123, "xxx", false};
byte[] bytes = serialization.serializeMulti(data);
Class[] classes = new Class[data.length];
for (int i = 0; i < data.length; i++) {
classes[i] = data[i].getClass();
}
data = serialization.deserializeMulti(bytes, classes);
assert data.length == 4 && data[2].toString().equals("xxx");
}
}
package org.hongxi.whatsmars.common.serialize;
import lombok.Data;
import org.msgpack.annotation.Message;
import java.io.Serializable;
@Message
@Data
public class User implements Serializable {
private static final long serialVersionUID = -7723128823885218090L;
String name;
int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册