利用Netty的ChannelBuffer自定义序列化

来源:互联网 发布:如何评价极限挑战知乎 编辑:程序博客网 时间:2024/06/11 09:10

利用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 <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> valueClz) {Map<K,V> 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> 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 = 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 <T> Serializer 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> Serializer writeMap(Map<K, V> map) {if (isEmpty(map)) {writeBuffer.writeShort((short) 0);return this;}writeBuffer.writeShort((short) map.size());for (Entry<K, V> 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 <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;}}
测试用例
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;}@Overrideprotected void read() {this.gradeId = readInt();this.gradeName = readString();}@Overrideprotected 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;@Overrideprotected void read() {this.studentId = readInt();this.name = readString();this.age = readInt();this.grade = read(Grade.class);}@Overrideprotected 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 {@Testpublic 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


原创粉丝点击