Netty 快速入门系列 - Chapter 6 自定义数据协议【第十五讲】自定义方法Serializer

如何自定义方法Serializer完成 String、List、Map等动态数据序列化呢?

Serializer 接口

 package com.john.netty.learn.ch08.core;
import org.jboss.netty.buffer.ChannelBuffer;

public interface Serializer {

public void writeToBuffer(ChannelBuffer writeChanneBuffer);
public void readByBuffer(ChannelBuffer channelBuffer) throws InstantiationException, IllegalAccessException;

}

AbstractSerializer

String序列化&反序列化: 长度+byte流 (注意:这里支持Null 通过-1区分)

public AbstractSerializer writeString(String value) {
if (value == null) {
writeBuffer.writeShort(-1);
return this;
}
byte[] bytes = value.getBytes(CHARSET);
writeBuffer.writeShort(bytes.length);
if (bytes.length > 0) {
writeBuffer.writeBytes(bytes);
}
return this;

}


public String readString() {
short length = this.readBuffer.readShort();
if (length == -1) {
return null;
}
if (length == 0) {
return "";

}

byte[] bytes = new byte[length];
readBuffer.readBytes(bytes);
return new String(bytes);
}

Date序列化&反序列化:  (注意:这里支持Null 通过0区分)

      public AbstractSerializer writeDate(Date date) {

if (date == null) {


writeBuffer.writeLong(0);
return this;
}

writeBuffer.writeLong(date.getTime());
return this;

}

public Date readDate() {

long l = readBuffer.readLong();


if (l == 0) {


return null;
}


return new Date(l);
}

    List序列化&反序列化: Size+Object byte流 (注意:这里支持Null 通过-1区分)

public <T> AbstractSerializer writeList(List<T> list) {

if (isEmpty(list)) {

writeBuffer.writeShort(list == null ? -1 : 0);

return this;
}

writeBuffer.writeShort((short) list.size());

for (T item : list) {
writeObject(item);
}

return this;

}


public <T> List<T> readList(Class<T> clz) throws InstantiationException, IllegalAccessException {

short s = readBuffer.readShort();

if (s == -1) {
return null;
}

List<T> list = new ArrayList<>(s);

for (int i = 0; i < s; i++) {
list.add(readObject(clz));
}

return list;

}

       Map序列化&反序列化: size + [Key Object & Value Object] (注意:这里支持Null 通过-1区分)

public <K, V> AbstractSerializer writeMap(Map<K, V> map) {


if (isEmpty(map)) {

writeBuffer.writeShort(map == null ? -1 : 0);

return this;
}
          
writeBuffer.writeShort((short) map.size());

for (Entry<K, V> entry : map.entrySet()) {
     
this.writeObject(entry.getKey());
this.writeObject(entry.getValue());
}


return this;

}

public <K, V> Map<K, V> readMap(Class<K> keyClz, Class<V> valClz)
throws InstantiationException, IllegalAccessException {

short s = readBuffer.readShort();

if (s == -1) {

return null;
}

Map<K, V> maps = new HashMap<>(s);

for (int i = 0; i < s; i++) {
maps.put(readObject(keyClz), readObject(valClz));
}

return maps;
}

AbstractSerializer 完成代码:

package com.john.netty.learn.ch08.core;

import java.lang.reflect.Array;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


import org.jboss.netty.buffer.ChannelBuffer;


public abstract class AbstractSerializer implements Serializer {


public static final Charset CHARSET = Charset.forName("UTF-8");


protected ChannelBuffer writeBuffer;


protected ChannelBuffer readBuffer;


protected AbstractSerializer() {


}


public void readByBuffer(ChannelBuffer channelBuffer) throws InstantiationException, IllegalAccessException {


this.readBuffer = channelBuffer;
this.read();


}


public byte[] getSerializerBytes() {


byte[] bytes = new byte[writeBuffer.writerIndex()];


writeBuffer.readBytes(bytes);


writeBuffer.clear();


return bytes;
}


public int readIntValue() {


return readBuffer.readInt();
}


public Integer readInt() {


byte b = readBuffer.readByte();


if (b == 0) {


return null;
}


return readBuffer.readInt();
}


public String readString() {


short length = this.readBuffer.readShort();


if (length == -1) {


return null;
}


if (length == 0) {
return "";
}
byte[] bytes = new byte[length];
readBuffer.readBytes(bytes);


return new String(bytes);
}


public long readLongValue() {


return readBuffer.readLong();
}


public Long readLong() {


byte b = readBuffer.readByte();


if (b == 0) {


return null;
}


return readBuffer.readLong();
}


public Date readDate() {


long l = readBuffer.readLong();


if (l == 0) {


return null;
}


return new Date(l);
}


public <T> List<T> readList(Class<T> clz) throws InstantiationException, IllegalAccessException {


short s = readBuffer.readShort();


if (s == -1) {


return null;
}


List<T> list = new ArrayList<>(s);


for (int i = 0; i < s; i++) {


list.add(readObject(clz));


}


return list;
}


public <K, V> Map<K, V> readMap(Class<K> keyClz, Class<V> valClz)
throws InstantiationException, IllegalAccessException {


short s = readBuffer.readShort();


if (s == -1) {


return null;
}


Map<K, V> maps = new HashMap<>(s);


for (int i = 0; i < s; i++) {


maps.put(readObject(keyClz), readObject(valClz));
}


return maps;
}


public <T> T readObject(Class<T> clz) throws InstantiationException, IllegalAccessException {


if (clz == Integer.class) {


return (T) readInt();
}


if (clz == Long.class) {


return (T) readLong();
}


if (clz == String.class) {


return (T) this.readString();
}


if (clz == Date.class) {


return (T) this.readDate();
}


if (List.class.isAssignableFrom(clz)) {


return (T) this.readList(clz);
}


if (Serializer.class.isAssignableFrom(clz)) {


byte b = this.readBuffer.readByte();


if (b == 0) {


return null;
}


Object obj = clz.newInstance();


((Serializer) obj).readByBuffer(readBuffer);


return (T) obj;


}


throw new IllegalArgumentException("不可序列化的类型:" + clz.getName());


}


/**
* 写入目标buff

* @param buffer
* @return
*/


public void writeToBuffer(ChannelBuffer writeChanneBuffer) {


this.writeBuffer = writeChanneBuffer;


this.write();


}


public ChannelBuffer writeToLocalBuff() {


writeBuffer = BufferFactory.getBuffer();


writeToBuffer(writeBuffer);


return writeBuffer;
}


public AbstractSerializer writeByte(byte value) {


writeBuffer.writeByte(value);


return this;
}


public AbstractSerializer writeByte(Byte value) {


if (value == null) {


writeBuffer.writeByte(0);
return this;
}


writeBuffer.writeByte(1);
writeBuffer.writeByte(value);


return this;
}


public AbstractSerializer writeShort(short value) {


writeBuffer.writeShort(value);


return this;
}


public AbstractSerializer writeShort(Short value) {


if (value == null) {


writeBuffer.writeByte(0);


return this;
}


writeBuffer.writeByte(1);
writeBuffer.writeShort(value);


return this;
}


public AbstractSerializer writeInt(int value) {


writeBuffer.writeInt(value);


return this;
}


public AbstractSerializer writeInt(Integer value) {


if (value == null) {


writeBuffer.writeByte(0);
return this;
}


writeBuffer.writeByte(1);
writeBuffer.writeInt(value);


return this;
}


public AbstractSerializer writeDouble(Double value) {


if (value == null) {


writeBuffer.writeByte(0);
return this;
}


writeBuffer.writeByte(1);
writeBuffer.writeDouble(value);


return this;
}


public AbstractSerializer writeDouble(double value) {


writeBuffer.writeDouble(value);


return this;
}


public AbstractSerializer writeLong(Long value) {


if (value == null) {


writeBuffer.writeByte(0);
return this;
}


writeBuffer.writeByte(1);
writeBuffer.writeLong(value);


return this;
}


public AbstractSerializer writeLong(long value) {


writeBuffer.writeLong(value);


return this;
}


public AbstractSerializer writeString(String value) {


if (value == null) {


writeBuffer.writeShort(-1);
return this;
}


byte[] bytes = value.getBytes(CHARSET);


writeBuffer.writeShort(bytes.length);


if (bytes.length > 0) {


writeBuffer.writeBytes(bytes);
}


return this;
}


public AbstractSerializer writeDate(Date date) {


if (date == null) {


writeBuffer.writeLong(0);


return this;
}


writeBuffer.writeLong(date.getTime());


return this;


}


public <T> AbstractSerializer writeList(List<T> list) {


if (isEmpty(list)) {


writeBuffer.writeShort(list == null ? -1 : 0);


return this;
}


writeBuffer.writeShort((short) list.size());


for (T item : list) {


writeObject(item);


}


return this;
}


public <K, V> AbstractSerializer writeMap(Map<K, V> map) {


if (isEmpty(map)) {


writeBuffer.writeShort(map == null ? -1 : 0);


return this;
}


writeBuffer.writeShort((short) map.size());


for (Entry<K, V> entry : map.entrySet()) {


this.writeObject(entry.getKey());
this.writeObject(entry.getValue());
}


return this;
}


public AbstractSerializer writeArray(Array array) {


if (isEmpty(array)) {


writeBuffer.writeShort(array == null ? -1 : 0);


return this;
}


int length = Array.getLength(array);


writeBuffer.writeShort(length);


for (int i = 0; i < length; i++) {


this.writeObject(Array.get(array, i));


}


return this;


}


private boolean isEmpty(Array array) {


return array == null || Array.getLength(array) == 0;
}


public AbstractSerializer writeObject(Object object) {


if (object instanceof Array) {


writeArray((Array) object);


return this;
}


if (object instanceof Byte) {


this.writeByte((Byte) object);


return this;
}


if (object instanceof Short) {


this.writeShort((Short) object);


return this;
}


if (object instanceof Integer) {


this.writeInt((Integer) object);


return this;
}


if (object instanceof Date) {


this.writeDate((Date) object);


return this;
}


if (object instanceof String) {


this.writeString((String) object);


return this;
}


if (object instanceof List) {


this.writeList((List) object);


return this;
}


if (object instanceof Map) {


this.writeMap((Map) object);


return this;
}


if (object instanceof Serializer) {


if (object == null) {


writeByte((byte) 0);


return this;
}


writeByte((byte) 1);


((Serializer) object).writeToBuffer(writeBuffer);


return this;


}


throw new IllegalArgumentException("不可序列化的类型:" + object.getClass());


}


/**
* 反序列化具体实现
*/
protected abstract void read() throws InstantiationException, IllegalAccessException;


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


private boolean isEmpty(Map map) {


return map == null || map.isEmpty();
}


private boolean isEmpty(List<?> list) {


return list == null || list.isEmpty();
}


}

测试:

MainSerializer 

package com.john.netty.learn.ch08;


import java.util.Arrays;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;


public class MainSerializer {


public static void main(String[] args) throws InstantiationException, IllegalAccessException {


Player player = new Player();


player.setId(null);
player.setAge(10);
player.setName("John hao");


Skill skill = new Skill();
skill.setType(1);
skill.setDesc("Fly");


player.addSkill(skill);


skill = new Skill();
skill.setType(2);
skill.setDesc("Run");


player.addSkill(skill);


player.addScope("Fly", 1);
player.addScope("Run", 2);
player.addScope("Unkown", 3);


player.writeToLocalBuff();


byte[] bytes = player.getSerializerBytes();


System.out.println(Arrays.toString(bytes));


ChannelBuffer channelBuffer = ChannelBuffers.wrappedBuffer(bytes);


Player player2 = new Player();
player2.readByBuffer(channelBuffer);


System.out.println(player2 + " scopes:" + player2.getScopes());


}


}


Player

package com.john.netty.learn.ch08;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.john.netty.learn.ch08.core.AbstractSerializer;

public class Player extends AbstractSerializer {

private Long id;

private String name;

private int age;

private List<Skill> skills = new ArrayList<>();

private Map<String, Integer> scopes = new HashMap<>();


public Player() {


}


public Map<String, Integer> getScopes() {
return scopes;
}


public void setScopes(Map<String, Integer> scopes) {
this.scopes = scopes;
}


public void addScope(String key, Integer value) {


scopes.put(key, value);
}


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 int getAge() {
return age;
}


public void setAge(int age) {
this.age = age;
}


public void addSkill(Skill skill) {
skills.add(skill);
}


public List<Skill> getSkills() {
return skills;
}


public void setSkills(List<Skill> skills) {
this.skills = skills;
}


@Override
protected void read() throws InstantiationException, IllegalAccessException {


this.id = this.readLong();
this.name = this.readString();
this.age = this.readIntValue();


this.skills = this.readList(Skill.class);

this.scopes = this.readMap(String.class, Integer.class);


}


@Override
protected void write() {


this.writeLong(this.id);
this.writeString(this.name);
this.writeInt(this.age);


this.writeList(skills);

this.writeMap(this.scopes);
}


@Override
public String toString() {


return "Id:" + this.id + " name:" + this.name + " age:" + this.age + " skills:" + this.skills;
}


}

package com.john.netty.learn.ch08;

import org.jboss.netty.buffer.ChannelBuffer;
import com.john.netty.learn.ch08.core.AbstractSerializer;
import com.john.netty.learn.ch08.core.Serializer;


public class Skill extends AbstractSerializer implements Serializer {


private int type;

private String desc;

public Skill() {


}


public int getType() {
return type;
}


public void setType(int type) {
this.type = type;
}


public String getDesc() {
return desc;
}


public void setDesc(String desc) {
this.desc = desc;
}


@Override
protected void read() {


this.type = this.readIntValue();
this.desc = this.readString();
}


@Override
protected void write() {


this.writeInt(this.type);
this.writeString(this.desc);
}



@Override
public String toString() {

return "Type:" + this.type +" Desc:" + this.desc;
}
}

所有源码下载 :https://download.csdn.net/download/netcobol/10308871

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值