alibaba / fastjson

FASTJSON 2.0.x has been released, faster and more secure, recommend you upgrade.
https://github.com/alibaba/fastjson2/wiki/fastjson_1_upgrade_cn
Apache License 2.0
25.74k stars 6.5k forks source link

使用parseObject 时报default constructor not found #1173

Open GuChuan opened 7 years ago

GuChuan commented 7 years ago

有一个类嵌套了其他的内部类

@Data
    public class SwitchContext {
    private String zoneName;
    private String clusterName;
    private ArrayList<TableTarget> tableTargets = new ArrayList<TableTarget>();
    private ZoneInfo zoneInfo;
    private ArrayList<TableTarget> runningQueue = new ArrayList<TableTarget>();
    private ArrayList<TableTarget> waittingQueue = new ArrayList<TableTarget>();
    private HashMap<TableTarget,String> invalidQueue = new HashMap<TableTarget, String>();
    private SwitchTask switchTask;
    private DecisionInfoMaintainer decisonInfoMaintainer = DecisionInfoMaintainer.getInstance();
    private HashMap<String,TableOnlineConfig> tableOnlineConfigHashMap;
    private HashMap<String,TableOfflineInfo> tableOfflineInfoHashMap;
    private HashMap<String,TableOnlineInfo> tableOnlineInfoHashMap;
    private HashMap<Long, TableDeployment> tableDeploymentHashMap;

使用 SwitchContext switchContext = parseObject(String s,SwitchContext.class ) 报异常:

com.alibaba.fastjson.JSONException: default constructor not found. class com.alibaba.search.autoumars.dataswitchcenter.model.TableOfflineInfo

我看网上有一种解法:http://blog.csdn.net/pengpenggxp/article/details/39181859

这种是需要从顶层类一直加到底层类吗?我有不少类都用了注解

wenshao commented 7 years ago

非静态内嵌类,建议添加static修饰符

GuChuan commented 7 years ago

@wenshao 是否只有这一种解法?

GuChuan commented 7 years ago

我发现一个问题,凡是用了@Data注解的类,parseObject的时候都会报default constructor not found,这个注解的运行机制应该和fastjson 解析的逻辑冲突了

wenshao commented 7 years ago

非静态内嵌类的缺省构造需要parent.this

halfhq commented 7 years ago

@wenshao 加入static也是无效的

    /**
     * {"state":1,"data":{"msg":"123"}}
     */
    void testInternalClass() {
        String json = "{\"state\":1,\"data\":{\"msg\":\"123\"}}";
        try {
            InternalClassTest c = JSON.parseObject(json, InternalClassTest.class);
            Log.d("JSON", "c.state=" + c.state + ", c.data.msg=" + (c.data == null ? "null" : c.data.msg));
        } catch (Exception e) {
            e.printStackTrace();    //com.alibaba.fastjson.JSONException: default constructor not found
        }
    }

    public static class InternalClassTest {
        public InternalClassTest() {
            super();
        }
        @JSONField(name = "state")
        public boolean state;
        @JSONField(name = "data")
        public Data data;

        public static class Data {
            public Data() {
                super();
            }
            @JSONField(name = "msg")
            public String msg;
        }
    }

依旧出现错误

om.alibaba.fastjson.JSONException: default constructor not found. class com.yyw.fastjson_example.MainActivit
   at com.alibaba.fastjson.util.JavaBeanInfo.build(Unknown Source)
   at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.<init>(Unknown Source)
   at com.alibaba.fastjson.parser.ParserConfig.createJavaBeanDeserializer(Unknown Source)
   at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(Unknown Source)
   at com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.getFieldValueDeserilizer(Unknown Sou
   at com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.parseField(Unknown Source)
   at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseField(Unknown Source)
   at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(Unknown Source)
   at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(Unknown Source)
   at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(Unknown Source)
   at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(Unknown Source)
   at com.alibaba.fastjson.JSON.parseObject(Unknown Source)
   at com.alibaba.fastjson.JSON.parseObject(Unknown Source)
   at com.alibaba.fastjson.JSON.parseObject(Unknown Source)
compile 'com.alibaba:fastjson:1.2.33'
compile 'com.alibaba:fastjson:1.1.58.android'

混淆:

fastjson

-dontwarn com.alibaba.fastjson. -keepattributes Signature -keepattributes Annotation -keep class com.alibaba.fastjson. { *; }

halfhq commented 7 years ago

1.使用static类 2.创建一个interface IFastJson,将此类的全部implements IFastJson 3.在proguard.txt中配置

-keep class * implements com.xxxx.IFastJson { public (***); }

faryang-sh commented 6 years ago

缺少了一个无参构造器,在需要序列化的类中加入一个无参构造器,如果用了liquibase,在序列化类中加入@NoArgsConstructor 注解

Nevall commented 6 years ago

解决办法: 1.使用static类 2.创建一个interface IFastJson,将此类的内部类实现implements IFastJson 3.在proguard.txt中配置 -keep class * implements com.xxxx.IFastJson

seefutureLee commented 5 years ago

是这样 如果我的bean有了带参数带构造方法 那必须再写一个无参数带构造方法 这样就不会报错了

Lyeluo commented 3 years ago

如果是没有源码,引用的第三方包呢?怎么办,不能提供无参构造呀