本文共 7420 字,大约阅读时间需要 24 分钟。
接上部分Netty3 - 自定义序列化协议(1)
示例(参照网络上一个示例来的)
支持基本数据,集合,Map,子对象的序列化
package custserialize.cust;import org.jboss.netty.buffer.ChannelBuffer;import java.nio.charset.Charset;import java.util.Collection;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.ArrayList;/** * 自定义序列化接口 */public abstract class CustSerializer { public static final Charset uft8Charset=Charset.forName("UTF-8"); protected ChannelBuffer writeBuffer; protected ChannelBuffer readBuffer; //反序列化 protected abstract void read(); //序列化 protected abstract void write(); /** * 从byte数组中获取数据 * @param bytes * @return */ public CustSerializer readFromBytes(byte[] bytes){ readBuffer=BufferFactory.getBuffer(bytes); read(); readBuffer.clear(); return this; } public void readFromBuffer(ChannelBuffer readBuffer){ this.readBuffer=readBuffer; read(); } /** * 写入本地的buffer * @return */ public ChannelBuffer writeToLocalBuffer(){ writeBuffer=BufferFactory.getBuffer(); write(); return writeBuffer; } /** * 写入指定的Buffer * @param channelBuffer * @return */ public ChannelBuffer writeToTargetBuffer(ChannelBuffer channelBuffer){ writeBuffer=channelBuffer; write(); return writeBuffer; } /** * 返回buffer 数组 * @return */ public byte[] getBytes(){ writeToLocalBuffer(); byte[] bytes=null; if(writeBuffer.writerIndex() == 0){ bytes=new byte[0]; }else{ bytes=new byte[writeBuffer.writerIndex()]; writeBuffer.readBytes(bytes);//数据copy到byte数组 } writeBuffer.clear(); return bytes; } public byte readByte(){ return readBuffer.readByte(); } public short readShort(){ return readBuffer.readShort(); } public int readInt(){ return readBuffer.readInt(); } public long readLong(){ return readBuffer.readLong(); } public float readFloat(){ return readBuffer.readFloat(); } public double readDouble(){ return readBuffer.readDouble(); } /** * 读取一人字符串 * @return */ public String readString(){ int size=readBuffer.readShort();//字符大小 if(size <=0){ return ""; } byte[] bytes=new byte[size]; readBuffer.readBytes(bytes); return new String(bytes,uft8Charset); } /** * 读取一个列表 * @param clz * @param* @return */ public List readList(Class clz){ List list = new ArrayList<>(); int size=readBuffer.readShort(); for(int i=0;i Map readMap(Class keyClz, Class valClz){ Map map=new HashMap (); int size=readBuffer.readShort(); for(int i=0;i I read(Class 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 == float.class || clz==Float.class){ t=this.readFloat(); }else if(clz == double.class || clz == Double.class){ t=readDouble(); }else if(clz == String.class){ t=readString(); }else if(CustSerializer.class.isAssignableFrom(clz)){ // try{ byte hasObejct=readBuffer.readByte(); if(hasObejct == 1){ CustSerializer temp=(CustSerializer)clz.newInstance(); temp.readFromBuffer(this.readBuffer); t=temp; }else{ t=null; } }catch (Exception ex){ ex.printStackTrace(); } }else { throw new RuntimeException("Not support class:"+clz); } return (I)t; } public CustSerializer writeByte(Byte value){ writeBuffer.writeByte(value); return this; } public CustSerializer writeShort(Short value){ writeBuffer.writeShort(value); return this; } public CustSerializer writeInt(Integer value){ writeBuffer.writeInt(value); return this; } public CustSerializer writeLong(Long value){ writeBuffer.writeLong(value); return this; } public CustSerializer writeFloat(Float value){ writeBuffer.writeFloat(value); return this; } public CustSerializer writeDouble(Double value){ writeBuffer.writeDouble(value); return this; } public CustSerializer writeList(List list){ if(isEmpty(list)){ writeBuffer.writeShort((short)0); return this; } writeBuffer.writeShort((short)list.size()); for(T item:list){ writeObject(item); } return this; } public CustSerializer writeMap(Map map){ if(isEmpty(map)){ writeBuffer.writeShort((short)0); return this; } writeBuffer.writeShort((short)map.size()); for(Map.Entry entry:map.entrySet()){ writeObject(entry.getKey()); writeObject(entry.getValue()); } return this; } public CustSerializer writeString(String value){ if(value ==null || value.isEmpty()){ writeShort((short)0); return this; } byte[] data = value.getBytes(uft8Charset); short len=(short)data.length; writeBuffer.writeShort(len); writeBuffer.writeBytes(data); return this; } public CustSerializer writeObject(Object object){ if(object == null){ writeByte((byte)0); }else{ if(object instanceof Integer){ writeInt((Integer) 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 CustSerializer){ this.writeByte((byte)1); CustSerializer value=(CustSerializer)object; value.writeToTargetBuffer(writeBuffer); return this; } throw new RuntimeException("Not supported serializer:"+object); } return this; } private boolean isEmpty(Collection c){ return c== null || c.size()==0; } private boolean isEmpty(Map c){ return c == null || c.size() == 0; }}
2.例子Employee实现自定义的序列化接口:
package custserialize.cust;public class Employee extends CustSerializer { private long id; private String name; private short age; public Employee(){ } @Override protected void read() { this.id=this.readLong(); this.name=this.readString(); this.age=this.readShort(); } @Override protected void write() { this.writeLong(id); this.writeString(name); this.writeShort(age); } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public short getAge() { return age; } public void setAge(short age) { this.age = age; } @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; }}
3.测试
package custserialize.cust;public class TestEmployee { public static void main(String[] args) { Employee employee=new Employee(); employee.setId(10001l); employee.setName("Gam"); employee.setAge((short)30); System.out.println("source emp:"+employee.toString()); byte[] bytes=employee.getBytes(); Employee emp1=new Employee(); emp1.readFromBytes(bytes); System.out.println("new emp="+emp1.toString()); }}
总结:自定义序列化协议已经结束:基本数据类型的储存,字节序列方案,二进制的表示(原码,反码,补码)等内容
转载地址:http://swadi.baihongyu.com/