123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 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;
- /**
- * <pre>
- *
- * Created by IntelliJ IDEA.
- * User: zhenqin
- * Date: 14-7-28
- * Time: 下午3:36
- * To change this template use File | Settings | File Templates.
- *
- * </pre>
- *
- * @author zhenqin
- */
- public class ProtobufSerializer implements Serializer<GeneratedMessage> {
- private static final long serialVersionUID = 1L;
- /**
- * 字符编码
- */
- protected String charset = "UTF-8";
- /**
- * 内部缓存
- */
- protected final static Map<Class<?>, Method>
- CLASS_METHOD_MAP = new HashMap<Class<?>, 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;
- }
- }
|