利用Netty的ChannelBuffer自定义序列化

利用Netty的ChannelBuffer自定义序列化

先定义ChannelBuffer工厂
package com.shux.common.serializer;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
/**
 * ChannelBuffer工厂
 * @author Simba.hua
 *
 */
public class BufferFactory {
	public static ChannelBuffer getBuffer(byte [] bytes){
		ChannelBuffer buffer = ChannelBuffers.copiedBuffer(bytes);
		return buffer;
	}
	public static ChannelBuffer getBuffer(){
		ChannelBuffer writeBuffer = ChannelBuffers.dynamicBuffer();
		return writeBuffer;
	}
}
自定义序列化类

package com.shux.common.serializer;


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;
/**
 * 自定义序列化类
 * @author Simba.hua
 *
 */
public abstract class Serializer {
	
	
	public static final Charset CHARSET = Charset.forName("UTF-8");
	
	protected ChannelBuffer writeBuffer;
	
	protected ChannelBuffer readBuffer;
	
	/**
	 * 反序列化具体实现
	 */
	protected abstract void read();
	
	/**
	 * 序列化具体实现
	 */
	protected abstract void write();
	
	/**
	 * 从byte数组获取数据
	 * @param bytes	读取的数组
	 */
	public Serializer readFromBytes(byte[] bytes) {
		readBuffer = BufferFactory.getBuffer(bytes);
		read();
		readBuffer.clear();
		return this;
	}
	
	/**
	 * 从buff获取数据
	 * @param readBuffer
	 */
	public void readFromBuffer(ChannelBuffer readBuffer) {
		this.readBuffer = readBuffer;
		read();
	}
	
	/**
	 * 写入本地buff
	 * @return
	 */
	public ChannelBuffer writeToLocalBuff(){
		writeBuffer = BufferFactory.getBuffer();
		write();
		return writeBuffer;
	}
	
	/**
	 * 写入目标buff
	 * @param buffer
	 * @return
	 */
	public ChannelBuffer writeToTargetBuff(ChannelBuffer buffer){
		writeBuffer = buffer;
		write();
		return writeBuffer;
	}
	
	/**
	 * 返回buffer数组
	 * 
	 * @return
	 */
	public byte[] getBytes() {
		writeToLocalBuff();
		byte[] bytes = null;
		if (writeBuffer.writerIndex() == 0) {
			bytes = new byte[0];
		} else {
			bytes = new byte[writeBuffer.writerIndex()];
			writeBuffer.readBytes(bytes);
		}
		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();
	}
	
	public String readString() {
		int size = readBuffer.readShort();
		if (size <= 0) {
			return "";
		}

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

		return new String(bytes, CHARSET);
	}
	
	public  List readList(Class clz) {
		List list = new ArrayList<>();
		int size = readBuffer.readShort();
		for (int i = 0; i < size; i++) {
			list.add(read(clz));
		}
		return list;
	}
	
	public  Map readMap(Class keyClz, Class valueClz) {
		Map map = new HashMap<>();
		int size = readBuffer.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 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 = readFloat();
		} else if (clz == double.class || clz == Double.class){
			t = readDouble();
		} else if (clz == String.class ){
			t = readString();
		} else if (Serializer.class.isAssignableFrom(clz)){
			try {
				byte hasObject = this.readBuffer.readByte();
				if(hasObject == 1){
					Serializer temp = (Serializer)clz.newInstance();
					temp.readFromBuffer(this.readBuffer);
					t = temp;
				}else{
					t = null;
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 
			
		} else {
			throw new RuntimeException(String.format("不支持类型:[%s]", clz));
		}
		return (I) t;
	}


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

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

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

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

	public Serializer writeFloat(Float value) {
		writeBuffer.writeFloat(value);
		return this;
	}

	public Serializer writeDouble(Double value) {
		writeBuffer.writeDouble(value);
		return this;
	}

	public  Serializer 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  Serializer writeMap(Map map) {
		if (isEmpty(map)) {
			writeBuffer.writeShort((short) 0);
			return this;
		}
		writeBuffer.writeShort((short) map.size());
		for (Entry entry : map.entrySet()) {
			writeObject(entry.getKey());
			writeObject(entry.getValue());
		}
		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;
		writeBuffer.writeShort(len);
		writeBuffer.writeBytes(data);
		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.writeToTargetBuff(writeBuffer);
				return this;
			}
			
			throw new RuntimeException("不可序列化的类型:" + object.getClass());
		}
		
		return this;
	}

	private  boolean isEmpty(Collection c) {
		return c == null || c.size() == 0;
	}
	public  boolean isEmpty(Map c) {
		return c == null || c.size() == 0;
	}
}
测试用例
package com.shux.common.serializer;

public class Grade extends Serializer{
	private int gradeId;
	private String gradeName;
	
	public int getGradeId() {
		return gradeId;
	}
	public void setGradeId(int gradeId) {
		this.gradeId = gradeId;
	}
	public String getGradeName() {
		return gradeName;
	}
	public void setGradeName(String gradeName) {
		this.gradeName = gradeName;
	}
	@Override
	protected void read() {
		this.gradeId = readInt();
		this.gradeName = readString();
		
	}
	@Override
	protected void write() {
		writeInt(gradeId);
		writeString(gradeName);
	}
}
package com.shux.common.serializer;

public class Student extends Serializer {
	private int studentId;
	private String name;
	private int age;
	private Grade grade;
	
	@Override
	protected void read() {
		this.studentId = readInt();
		this.name = readString();
		this.age = readInt();
		this.grade = read(Grade.class);

	}

	@Override
	protected void write() {
		writeInt(studentId);
		writeString(name);
		writeInt(age);
		writeObject(grade);

	}

	public int getStudentId() {
		return studentId;
	}

	public void setStudentId(int studentId) {
		this.studentId = studentId;
	}

	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 Grade getGrade() {
		return grade;
	}

	public void setGrade(Grade grade) {
		this.grade = grade;
	}

}

package com.shux.common.serializer;

import java.util.Arrays;

import org.junit.Test;

public class MySerializerTest {
	@Test
	public void testSerializser(){
		Grade grade = new Grade();
		grade.setGradeId(10);
		grade.setGradeName("班级1");
		Student student = new Student();
		student.setGrade(grade);
		student.setStudentId(100);
		student.setName("华晨曦");
		student.setAge(2);
		
		byte [] bytes = student.getBytes();
		//序列化后的数组
		System.out.println(Arrays.toString(bytes));
		
		//反序列化
		Student student1 = (Student) student.readFromBytes(bytes);
		System.out.println("studentID:"+student.getStudentId() +" name:"+student1.getName()+" age:"+student1.getAge()
		 					+" gradeId:"+student1.getGrade().getGradeId()+" gradeName:"+student1.getGrade().getGradeName());
	}
}
结果输出:
[0, 0, 0, 100, 0, 9, -27, -115, -114, -26, -103, -88, -26, -101, -90, 0, 0, 0, 2, 1, 0, 0, 0, 10, 0, 7, -25, -113, -83, -25, -70, -89, 49]
studentID:100 name:华晨曦 age:2 gradeId:10 gradeName:班级1


你可能感兴趣的:(利用Netty的ChannelBuffer自定义序列化)