美文网首页
hessian2序列化,扩展dubbo序列化协议

hessian2序列化,扩展dubbo序列化协议

作者: 路过的人儿 | 来源:发表于2021-02-22 11:11 被阅读0次

    扩展dubbo的序列化协议

    一、在main/java下新建包,并新增一下三个文件

    PersistentObjectOutput.java 实现ObjectOutput接口

    package com.heytap.ad.cpd.management.serialization;
    
    import com.alibaba.com.caucho.hessian.io.Hessian2Output;
    import org.apache.dubbo.common.serialize.ObjectOutput;
    
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class PersistentObjectOutput implements ObjectOutput{
        private final Hessian2Output mH2o;
        //注意:设置Output的Factory为上面自己定义的序列化工厂类
        public PersistentObjectOutput(OutputStream os) {
            this.mH2o = new Hessian2Output(os);
            this.mH2o.setSerializerFactory(PersistentSerializerFactory.TESTSERIALIZER_FACTORY);
        }
    
        @Override
        public void writeBool(boolean v) throws IOException {
            this.mH2o.writeBoolean(v);
        }
        @Override
        public void writeByte(byte v) throws IOException {
            this.mH2o.writeInt(v);
        }
        @Override
        public void writeShort(short v) throws IOException {
            this.mH2o.writeInt(v);
        }
        @Override
        public void writeInt(int v) throws IOException {
            this.mH2o.writeInt(v);
        }
        @Override
        public void writeLong(long v) throws IOException {
            this.mH2o.writeLong(v);
        }
        @Override
        public void writeFloat(float v) throws IOException {
            this.mH2o.writeDouble((double)v);
        }
        @Override
        public void writeDouble(double v) throws IOException {
            this.mH2o.writeDouble(v);
        }
        @Override
        public void writeBytes(byte[] b) throws IOException {
            this.mH2o.writeBytes(b);
        }
        @Override
        public void writeBytes(byte[] b, int off, int len) throws IOException {
            this.mH2o.writeBytes(b, off, len);
        }
        @Override
        public void writeUTF(String v) throws IOException {
            this.mH2o.writeString(v);
        }
        @Override
        public void writeObject(Object obj) throws IOException {
            this.mH2o.writeObject(obj);
        }
        @Override
        public void flushBuffer() throws IOException {
            this.mH2o.flushBuffer();
        }
    }
    

    PersistentSerialization.java

    package com.heytap.ad.cpd.management.serialization;
    
    import org.apache.dubbo.common.URL;
    import org.apache.dubbo.common.serialize.ObjectInput;
    import org.apache.dubbo.common.serialize.ObjectOutput;
    import org.apache.dubbo.common.serialize.Serialization;
    import org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class PersistentSerialization implements Serialization {
        @Override
        //注意,由于dubbo有很多序列化方式的扩展,每种方式有自己的id,自定义id时注意冲突,重复时会有ERROR提示
        public byte getContentTypeId() {
            return 22;
        }
        @Override
        public String getContentType() {
            return "persistent";
        }
        @Override
        public ObjectOutput serialize(URL url, OutputStream out) throws IOException {
            return new PersistentObjectOutput(out);
        }
        @Override
        public ObjectInput deserialize(URL url, InputStream is) throws IOException {
            return new Hessian2ObjectInput(is);
        }
    }
    

    PersistentSerializerFactory .java

    package com.heytap.ad.cpd.management.serialization;
    
    import com.alibaba.com.caucho.hessian.io.*;
    
    
    import java.io.IOException;
    import java.io.Serializable;
    import java.util.*;
    
    public class PersistentSerializerFactory extends SerializerFactory{
        public static final SerializerFactory TESTSERIALIZER_FACTORY = new PersistentSerializerFactory();
    
        public PersistentSerializerFactory() {
        }
    
        @Override
        public ClassLoader getClassLoader() {
            return Thread.currentThread().getContextClassLoader();
        }
        private HibernateListSerializer listSerializer = new HibernateListSerializer();
    
        @Override
        @SuppressWarnings("rawtypes")
        //序列化时,判断persistent相关类型,添加持久化对象的序列化方式,如果不是,则走父类的序列化方法
        public Serializer getSerializer(Class cl) throws HessianProtocolException {
            if (List.class.isAssignableFrom(cl)) {
                return listSerializer;
            }
            return super.getSerializer(cl);
        }
    
    
        private static class HibernateListSerializer implements Serializer {
            @Override
            @SuppressWarnings({"unchecked", "rawtypes"})
            public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
                if (!out.addRef(obj)) {
                    Collection list = (Collection)obj;
                    Class cl = obj.getClass();
                    boolean hasEnd;
                    Iterator iter = list.iterator();
    // 如果是list或者是set则进入下面操作,默认 hessian只支持arrayList的序列化。会报java.util.List cannot be assigned from null 这个错误
                    if (obj instanceof Set || obj instanceof List
                            || !Serializable.class.isAssignableFrom(cl)) {
                        hasEnd = out.writeListBegin(list.size(), null);
                    } else {
                        hasEnd = out.writeListBegin(list.size(), obj.getClass().getName());
                    }
                    while(iter.hasNext()) {
                        Object value = iter.next();
                        out.writeObject(value);
                    }
    
                    if (hasEnd) {
                        out.writeListEnd();
                    }
    
                }
            }
    
        }
    
    
    }
    

    二、在resource下新建 resources\META-INF\dubbo ,然后新建文本文件org.apache.dubbo.common.serialize.Serialization,并写入

    persistent=com.heytap.ad.cpd.management.serialization.PersistentSerialization
    

    三、更改dubbo的启动序列化协议,可以在参数上修改-Ddubbo.protocol.serialization=persistent,也可以在配置上修改 dubbo.protocol.serialization=fastjson

    相关文章

      网友评论

          本文标题:hessian2序列化,扩展dubbo序列化协议

          本文链接:https://www.haomeiwen.com/subject/myuhfltx.html