jackson IOException:不能将 Class com.mycompany.models.Person$Address(非静态成员类类型)反序列化为 Bean

2022-09-04 20:29:11

我有一个看起来像这样的类:

public class Person {
    public class Address {
        private String line1;
        private String line2;
        private String zipCode;
        private String state;

        // standard public getters and setters for the class here
   }

private String name;
private String address;

// standard public getters and setters for the class here

}

这就是我如何使用杰克逊。

public class JsonTest {
    public static <T> Object fromJson(String jsonAsString, Class<T> pojoClass)
throws JsonMappingException, JsonParseException, IOException {
        return m.readValue(jsonAsString, pojoClass);
    }

    public static String toJson(Object pojo, boolean prettyPrint)
throws JsonMappingException, JsonGenerationException, IOException {
        StringWriter sw = new StringWriter();
        JsonGenerator jg = jf.createJsonGenerator(sw);
        if (prettyPrint) {
            jg.useDefaultPrettyPrinter();
        }
        m.writeValue(jg, pojo);
        return sw.toString();
    }

    public static void main(String[] args) {
         Person p = new Person();
         String json = this.toJson(p, true); // converts ‘p’ to JSON just fine
         Person personFromJson = this.fromJson(json, Person.class); // throws exception!!!
    }
}

main 方法的第 3 行(我尝试将 json 转换为 Person 对象)抛出以下异常:

IOException: Can not deserialize Class com.mycompany.models.Person$Address (of type non-static member class) as a Bean

我做错了什么?


答案 1

由于内部类没有默认的零参数构造函数(它们具有对外部/父类的隐藏引用),因此 Jackson 无法实例化它们。

解决方案是使用内部类:static

public class Outer {
    static class Inner {
        private String foo;
        public String getFoo() { return foo; }
    }
}

原始答案

实现中存在一些问题,似乎无法序列化此类类,有关详细信息,请参阅 cowtowncoder


答案 2

正确,这曾经是当前杰克逊版本(1.8及更早版本)无法做到的事情。但是,内部类是绝对必要的非静态的吗?如果没有,只需在地址声明中添加“静态”即可正常工作;问题在于非静态内部类通过构造函数获取的“隐藏”this 指针。

Jackson 1.9 实际上将支持非静态内部类的简单用法的反序列化,请参阅此 Jira 条目