Skip to content

[BUG] 根据接口生成的cglib代理对象,序列化时结果为 {} #3445

@takemehand25

Description

@takemehand25

问题描述

简要描述您碰到的问题。
例如我有Account 接口,该接口设有get set 方法,创建cglib代理对象时,会给它添加Map接口,实际该接口创建的实例可以是Map类型,JSON序列化时也是期望该该实例被当做JSON来序列化

通过源代码发现
com.alibaba.fastjson2.writer.ObjectWriterProvider#getObjectWriterInternal
方法中,将我的接口的类型,改为了接口的父类Object类型,导致数据不能被正确序列化

在以下代码中,判断 objectClass 是代理类,就将我的原始类替换成了 Object类

        if (TypeUtils.isProxy(objectClass)) {
            if (objectClass == objectType) {
                objectType = superclass;
            }
            objectClass = superclass;
            if (fieldBased) {
                fieldBased = false;
                objectWriter = cacheFieldBased.get(objectType);
                if (objectWriter != null) {
                    return objectWriter;
                }
            }
        }

环境信息

请填写以下信息:

  • OS信息: windows10
  • JDK信息: jdk1.8
  • 版本信息:2.0.52

重现步骤

如何操作可以重现该问题:

  1. 使用 xxx.xxx 方法
  2. 输入 ... 数据
  3. 出现 ... 错误
//可在此输入示例代码

package com.takemehand;

import com.alibaba.fastjson2.JSON;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class Main {

    public static void main(String[] args) {

        Class targetClass = Account.class;
        Enhancer enhancer = new Enhancer();
        enhancer.setUseCache(true);
        List<Class<?>> superInterfaces = new ArrayList<Class<?>>();
        if (targetClass.isInterface()) {
            superInterfaces.add(targetClass);
            superInterfaces.add(Map.class);
        }
        enhancer.setInterfaces(superInterfaces.toArray(new Class[0]));
        enhancer.setCallback(new MethodInterceptor() {
            Map<Object, Object> map = new LinkedHashMap<>();
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                String mname = method.getName();
                int mname_len = mname.length();

                if (mname.startsWith("set") && method.getReturnType() == void.class){
                    map.put(mname.substring(3, mname_len).toLowerCase(), objects[0]);
                    return null;
                }
                if (mname_len == 3 && "put".equals(mname)) {
                    //非克隆对象
                    return map.put(objects[0], objects[1]);
                }
                if (mname_len == 3 && "get".equals(mname)) {
                    //非克隆对象
                    return map.get(objects[0]);
                }
                if (mname.equals("entrySet")){
                    return map.entrySet();
                }
                return null;
            }
        });

        Account account = (Account) enhancer.create();
        account.setName("test");
        account.setPassword("123");

        System.out.println(JSON.toJSONString(account));

    }
}


public interface Account  {
    public String getName() ;

    public void setName(String name);

    public String getPassword() ;

    public void setPassword(String password) ;
}

期待的正确结果

对您期望发生的结果进行清晰简洁的描述。

期望在对代理对象的判断时,当 superclass 是 Object 时,不替换 objectClass

相关日志输出

请复制并粘贴任何相关的日志输出。

附加信息

如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixed

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions