zoukankan      html  css  js  c++  java
  • hessian 反序列化问题

    有class 比如

    class Test{

    private TestArrayList list=new TestArrayList("");

    public static void main(String args[]){

    Test t=new Test();

     byte[] b=hessian encode ;

     Test r =(Test)hessian decode

    }

    }

    class TestArrayList extends ArrayList{

      public TestArrayList(String a){}

    }

    反序列化后Test对象里的list不再是TestArrayList,而是 ArrayList类型

    分析hessian反序列化源码

    Hessian2Input.java

    public Object readObject(Class cl){
      //省略
        case 0x70: case 0x71: case 0x72: case 0x73:
        case 0x74: case 0x75: case 0x76: case 0x77:
          {
        int length = tag - 0x70;
    
        String type = readType();
          
        Deserializer reader;
            
        reader = findSerializerFactory().getListDeserializer(type, cl);
        //关键处
        Object v = reader.readLengthList(this, length);
    
        return v;
          }    
    
    }

    跳转到

    CollectionDeserializer.java

    public Object readLengthList(AbstractHessianInput in, int length)
        throws IOException
      {
        Collection list = createList();
    
        in.addRef(list);
    
        for (; length > 0; length--)
          list.add(in.readObject());
    
        return list;
      }
    
    private Collection createList()
        throws IOException
      {
        Collection list = null;
        
        if (_type == null)
          list = new ArrayList();
        else if (! _type.isInterface()) {
          try {
    //关键处 list
    = (Collection) _type.newInstance(); } catch (Exception e) { } } if (list != null) { } else if (SortedSet.class.isAssignableFrom(_type)) list = new TreeSet(); else if (Set.class.isAssignableFrom(_type)) list = new HashSet(); else if (List.class.isAssignableFrom(_type)) list = new ArrayList(); else if (Collection.class.isAssignableFrom(_type)) list = new ArrayList(); //省略 }
    list = (Collection) _type.newInstance();尝试调用TestArrayList的无参构造函数,但因为没有无参构造函数,抛出异常,走到下面的list = new ArrayList();逻辑

    我们看看newInstance()做了什么事情
    public T newInstance()
            throws InstantiationException, IllegalAccessException
        {
            if (System.getSecurityManager() != null) {
                checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
            }
    
            // NOTE: the following code may not be strictly correct under
            // the current Java memory model.
    
            // Constructor lookup
            if (cachedConstructor == null) {
                if (this == Class.class) {
                    throw new IllegalAccessException(
                        "Can not call newInstance() on the Class for java.lang.Class"
                    );
                }
                try {
                    Class<?>[] empty = {};
                    final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
      //省略
    }

    private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
                                            int which) throws NoSuchMethodException
        {
            Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
    //这里parameterTypes是空数组,constructors不为空
            for (Constructor<T> constructor : constructors) {
    //数组比较长度不一致,抛出异常
                if (arrayContentsEq(parameterTypes,
                                    constructor.getParameterTypes())) {
                    return getReflectionFactory().copyConstructor(constructor);
                }
            }
            throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
        }

    因此我们如果调用hessian序列化对象的时候,一定要注意对象里面的自定义属性是否有默认构造函数,不然会引起奇怪的问题

  • 相关阅读:
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第一题
    fiddler模拟发送post请求
  • 原文地址:https://www.cnblogs.com/devilwind/p/8889394.html
Copyright © 2011-2022 走看看