您的位置:首页 > 其它

Netty学习8-自定义复杂序列化框架

2017-01-06 10:11 399 查看
1 概述

《Netty学习7-序列化原理》一文中讲述了序列化的原理,通过Java位运算、JDK原生的NIO、Netty的ChannelBuffer做了序列化操作。本文演示稍微复杂的一个自定义序列化框架,但万变不离其宗,拆解出来还是很简单的。

2 工具类

这是核心类。拆解来看就是调用了ChannelBuffer的readInt和writeInt等方法,并定义了抽象类方法read和write等待实体类实现。

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
/**
* Buffer工具类
*/
public class BufferUtils {

/**
* 获取一个缓存对象
*
* @return 缓存对象
*/
public static ChannelBuffer getBuffer() {
ChannelBuffer dynamicBuffer = ChannelBuffers.dynamicBuffer();
return dynamicBuffer;
}

/**
* 将二进制bytes写入缓存对象
*
* @param bytes 二进制数据
* @return 缓存对象
*/
public static ChannelBuffer getBuffer(byte[] bytes) {
ChannelBuffer copiedBuffer = ChannelBuffers.copiedBuffer(bytes);
return copiedBuffer;
}
}

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.jboss.netty.buffer.ChannelBuffer;
import com.cn.core.BufferFactory;
/**
* 自定义序列化基类
*/
public abstract class Serializer {

// 编码对象
public static final Charset CHARSET = Charset.forName("UTF-8");

// 写缓存
protected ChannelBuffer writeBuf;

// 读缓存
protected ChannelBuffer readBuf;

// 反序列化具体实现
protected abstract void read();

// 序列化具体实现
protected abstract void write();

/***************************************** 序列化 ************************************/

// 序列化
public byte[] serialze() {

// 申明写缓存
writeBuf = BufferUtils.getBuffer();

// 将数据写入写缓存
write();

// 将写缓存数据读入byte数组
byte[] bytes = null;
if (writeBuf.writerIndex() == 0)
bytes = new byte[0];
else {
bytes = new byte[writeBuf.writerIndex()];
writeBuf.readBytes(bytes);
}
writeBuf.clear();
return bytes;
}

public Serializer writeShort(Short value) {
writeBuf.writeShort(value);
return this;
}

public Serializer writeInt(Integer value) {
writeBuf.writeInt(value);
return this;
}

public Serializer writeLong(Long value) {
writeBuf.writeLong(value);
return this;
}

public Serializer writeString(String value) {
if (value == null || value.isEmpty()) {
writeShort((short) 0);
return this;
}
byte data[] = value.getBytes(CHARSET);
short len = (short) data.length;
writeBuf.writeShort(len);
writeBuf.writeBytes(data);
return this;
}

public Serializer writeByte(Byte value) {
writeBuf.writeByte(value);
return this;
}

public <T> Serializer writeList(List<T> list) {
if (isEmpty(list)) {
writeBuf.writeShort((short) 0);
return this;
}
writeBuf.writeShort((short) list.size());
for (T item : list) {
writeObject(item);
}
return this;
}

public <K, V> Serializer writeMap(Map<K, V> map) {
if (isEmpty(map)) {
writeBuf.writeShort((short) 0);
return this;
}
writeBuf.writeShort((short) map.size());
for (Entry<K, V> entry : map.entrySet()) {
writeObject(entry.getKey());
writeObject(entry.getValue());
}
return this;
}

public Serializer writeObject(Object object) {
if (object == null) {
writeByte((byte) 0);
} else {
if (object instanceof Integer) {
writeInt((int) object);
return this;
}
if (object instanceof Long) {
writeLong((long) object);
return this;
}
if (object instanceof Short) {
writeShort((short) object);
return this;
}
if (object instanceof Byte) {
writeByte((byte) object);
return this;
}
if (object instanceof String) {
String value = (String) object;
writeString(value);
return this;
}
if (object instanceof Serializer) {
writeByte((byte) 1);
Serializer value = (Serializer) object;
value.writeToTargetBuffer(writeBuf);
return this;
}
throw new RuntimeException("不可序列化的类型:" + object.getClass());
}
return this;
}

// 调用对象自身的写入方法
public ChannelBuffer writeToTargetBuffer(ChannelBuffer buffer) {
writeBuf = buffer;
write();
return writeBuf;
}

/***************************************** 反序列化 ************************************/

public Serializer deserialize(byte[] bytes) {
readBuf = BufferUtils.getBuffer(bytes);
read();
readBuf.clear();
return this;
}

public byte readByte() {
return readBuf.readByte();
}

public short readShort() {
return readBuf.readShort();
}

public int readInt() {
return readBuf.readInt();
}

public long readLong() {
return readBuf.readLong();
}

public String readString() {
int size = readBuf.readShort();
if (size <= 0) {
return "";
}

byte[] bytes = new byte[size];
readBuf.readBytes(bytes);

return new String(bytes, CHARSET);
}

public <T> List<T> readList(Class<T> clz) {
List<T> list = new ArrayList<>();
int size = readBuf.readShort();
for (int i = 0; i < size; i++) {
list.add(read(clz));
}
return list;
}

public <K, V> Map<K, V> readMap(Class<K> keyClz, Class<V> valueClz) {
Map<K, V> map = new HashMap<>();
int size = readBuf.readShort();
for (int i = 0; i < size; i++) {
K key = read(keyClz);
V value = read(valueClz);
map.put(key, value);
}
return map;
}

@SuppressWarnings("unchecked")
public <I> I read(Class<I> clz) {
Object t = null;
if (clz == int.class || clz == Integer.class) {
t = this.readInt();
} else if (clz == byte.class || clz == Byte.class) {
t = this.readByte();
} else if (clz == short.class || clz == Short.class) {
t = this.readShort();
} else if (clz == long.class || clz == Long.class) {
t = this.readLong();
} else if (clz == String.class) {
t = readString();
} else if (Serializer.class.isAssignableFrom(clz)) {
try {
byte hasObject = this.readBuf.readByte();
if (hasObject == 1) {
Serializer temp = (Serializer) clz.newInstance();
temp.readFromBuffer(this.readBuf);
t = temp;
} else {
t = null;
}
} catch (Exception e) {
e.printStackTrace();
}

} else {
throw new RuntimeException(String.format("不支持类型:[%s]", clz));
}
return (I) t;
}

// 调用对象自身的读取方法
public void readFromBuffer(ChannelBuffer readBuffer) {
this.readBuf = readBuffer;
read();
}

/***************************************** 工具方法 ************************************/

private <T> boolean isEmpty(Collection<T> c) {
return c == null || c.size() == 0;
}

public <K, V> boolean isEmpty(Map<K, V> c) {
return c == null || c.size() == 0;
}
}


3 实体类

public class Hobby extends Serializer {

private String name;

public Hobby() {

}

@Override
protected void read() {
this.name = readString();
}

@Override
protected void write() {
writeString(name);
}

public Hobby(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Hobby [name=" + name + "]";
}
}

public class Student extends Serializer {

// 学号
private Integer id;
// 姓名
private String name;
// 分数
private Long mark;
// 同学名
private List<String> classmates;
// 爱好
private List<Hobby> hobbies;
// 住址
private Map<String, String> address;

@Override
protected void write() {
writeInt(id);
writeString(name);
writeLong(mark);
writeList(classmates);
writeList(hobbies);
writeMap(address);
}

@Override
protected void read() {
this.id = readInt();
this.name = readString();
this.mark = readLong();
this.classmates = readList(String.class);
this.hobbies = readList(Hobby.class);
this.address = readMap(String.class, String.class);
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public Long getMark() {
return mark;
}

public void setMark(Long mark) {
this.mark = mark;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public List<String> getClassmates() {
return classmates;
}

public void setClassmates(List<String> classmates) {
this.classmates = classmates;
}

public List<Hobby> getHobbies() {
return hobbies;
}

public void setHobbies(List<Hobby> hobbies) {
this.hobbies = hobbies;
}

public Map<String, String> getAddress() {
return address;
}

public void setAddresses(Map<String, String> address) {
this.address = address;
}

@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", mark=" + mark
+ ", classmates=" + classmates + ", hobbies=" + hobbies
+ ", address=" + address + "]";
}
}


4 测试方法

public class XYTest {
public static void main(String[] args) {

// 数据初始化
Student student = new Student();
student.setId(10);
student.setName("xy");
student.setMark(100L);
List<String> classmates = new ArrayList<String>();
classmates.add("xiaoming");
classmates.add("xiaohong");
student.setClassmates(classmates);
List<Hobby> hobbies = new ArrayList<Hobby>();
hobbies.add(new Hobby("football"));
student.setHobbies(hobbies);
Map<String, String> address = new HashMap<String, String>();
address.put("aaa", "bbb");
address.put("ccc", "ddd");
student.setAddresses(address);

// 序列化
byte[] array = student.serialze();
System.out.println(Arrays.toString(array));

// 反序列化
Student s = new Student();
s.deserialize(array);
System.out.println(s.toString());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐