Netty学习8-自定义复杂序列化框架
2017-01-06 10:11
399 查看
1 概述
《Netty学习7-序列化原理》一文中讲述了序列化的原理,通过Java位运算、JDK原生的NIO、Netty的ChannelBuffer做了序列化操作。本文演示稍微复杂的一个自定义序列化框架,但万变不离其宗,拆解出来还是很简单的。
2 工具类
这是核心类。拆解来看就是调用了ChannelBuffer的readInt和writeInt等方法,并定义了抽象类方法read和write等待实体类实现。
3 实体类
4 测试方法
《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()); } }
相关文章推荐
- Netty学习9-序列化框架protocbuf
- 框架学习之Struts2 第五节 自定义拦截器
- 【学习】WCF的服务契约、复杂类型序列化、消息契约的实现续-IXmlSerializable与MessageContract
- 关于后盾网yii框架的学习小结(8)--自定义前台的验证
- rpc框架之 avro 学习 2 - 高效的序列化
- 基于Netty的RPC简单框架实现(三):Kryo实现序列化
- C#学习实例-将比较复杂的结构序列化到文件中
- Netty学习:搭建一个简单的Netty服务(JAVA NIO 类库的异步通信框架)
- JDBC 学习笔记(四)—— 自定义JDBC框架+Apache—DBUtils框架+事务管理+操作多表 - 解无邪
- Netty框架学习(一)
- 简单4步在win7 X64+cuda7.5或cuda8.0+VS2013环境中配置caffe深度学习框架,不用配置复杂的依赖库。
- C#温故而知新学习系列之XML编程—XmlSerializer类把复杂对象序列化为XML文档(六)
- 自定义View的框架学习
- 一步一个脚印学习WCF系列之WCF契约设计—3-复杂类型序列化之数据契约DataContractAttribute
- Transitions框架学习(三)—— 自定义转场
- 【学习】WCF的服务契约、复杂类型序列化、消息契约的实现
- .NET 插件系统框架设计(二) 使用对象序列化实现自定义配置文件管理
- 多语言跨平台序列化框架Google Protobuf-Python connect Netty
- .Java程序员从笨鸟到菜鸟之(四十七)细谈struts2(九)内置拦截器和自定义拦截器详解(附源码) 分类: 学习专区 框架Struts2 Java程序员从笨鸟到菜鸟 2012-05-08 12:
- XML序列化与反序列化+自定义XML注解框架XmlUtils