接上部分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 <T>
* @return
*/
public <T> List<T> readList(Class<T> clz){
List<T> list = new ArrayList<>();
int size=readBuffer.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> valClz){
Map<K,V> map=new HashMap<K, V>();
int size=readBuffer.readShort();
for(int i=0;i<size;i++){
K key=read(keyClz);
V value=read(valClz);
map.put(key,value);
}
return map;
}
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 == 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 <T> CustSerializer writeList(List<T> list){
if(isEmpty(list)){
writeBuffer.writeShort((short)0);
return this;
}
writeBuffer.writeShort((short)list.size());
for(T item:list){
writeObject(item);
}
return this;
}
public <K,V> CustSerializer writeMap(Map<K,V> map){
if(isEmpty(map)){
writeBuffer.writeShort((short)0);
return this;
}
writeBuffer.writeShort((short)map.size());
for(Map.Entry<K,V> 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 <T> boolean isEmpty(Collection<T> c){
return c== null || c.size()==0;
}
private <K,V> boolean isEmpty(Map<K,V> 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());
}
}
总结:自定义序列化协议已经结束:基本数据类型的储存,字节序列方案,二进制的表示(原码,反码,补码)等内容