package com.sdyc.ndmp.protobuf.serializer; import com.google.protobuf.GeneratedMessage; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; /** *
 *
 * Created by IntelliJ IDEA.
 * User: zhenqin
 * Date: 14-7-28
 * Time: 下午3:36
 * To change this template use File | Settings | File Templates.
 *
 * 
* * @author zhenqin */ public class ProtobufSerializer implements Serializer { private static final long serialVersionUID = 1L; /** * 字符编码 */ protected String charset = "UTF-8"; /** * 内部缓存 */ protected final static Map, Method> CLASS_METHOD_MAP = new HashMap, Method>(3); public ProtobufSerializer() { } public ProtobufSerializer(String charset) { this.charset = charset; } @Override public byte[] serialize(GeneratedMessage o) { if (o == null) { return null; } byte[] bytes = o.toByteArray(); String clazz = o.getClass().getName(); byte[] bytes1 = clazz.getBytes(Charset.forName(charset)); ByteBuf channelBuffer = Unpooled.buffer(4 + bytes.length + bytes1.length); channelBuffer.writeInt(bytes1.length); channelBuffer.writeBytes(bytes1); channelBuffer.writeBytes(bytes); return channelBuffer.array(); } @Override public GeneratedMessage deserialize(byte[] bytes) { if (bytes == null || bytes.length == 0) { return null; } ByteBuf channelBuffer = Unpooled.wrappedBuffer(bytes); channelBuffer.resetReaderIndex(); int classNameLength = channelBuffer.readInt(); ByteBuf classBuf = channelBuffer.readBytes(classNameLength); String clazzName = classBuf.toString(Charset.forName(charset)); ByteBuf objectBuf = channelBuffer.readBytes(channelBuffer.readableBytes()); // 检查一下Netty Protobuf解码器是怎么写的 try { return reflact(clazzName, objectBuf.array()); } catch (ClassNotFoundException e) { throw new IllegalStateException("class: " + clazzName + " not found!", e); } catch (NoSuchMethodException e) { throw new IllegalStateException("class: " + clazzName + " has not method: parseFrom(byte[]).", e); } catch (Exception e) { throw new IllegalStateException("reflection error!", e); } } protected static GeneratedMessage reflact(String clazz, byte[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class aClass = Class.forName(clazz); Method method = CLASS_METHOD_MAP.get(aClass); if (method == null) { method = aClass.getMethod("parseFrom", byte[].class); CLASS_METHOD_MAP.put(aClass, method); } return (GeneratedMessage) method.invoke(null, args); } public String getCharset() { return charset; } public void setCharset(String charset) { this.charset = charset; } }