jackson IOException: Can not deserialize Class com

2020-07-03 03:23发布

问题:

I have a class that looks like this:

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

}

and here’s how I am using jackson with it.

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!!!
    }
}

the 3rd line of the main method (where I try to convert json to Person object), throws this exception:

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

what am I doing wrong?

回答1:

Because inner classes do not have a default zero argument constructor (they have a hidden reference to the outer/parent class) Jackson cannot instantiate them.

The solution is to use static inner classes:

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

Original Answer:

There are some issues in implementation and it seems like you can't serialize such classes, see cowtowncoder for details.



回答2:

Correct, this used to be something you can not do with current Jackson versions (1.8 and earlier). But is it absolutely necessary for inner class to be non-static? If not, just add 'static' in declaration of Address and it'll work fine; problem is with the "hidden" this-pointer that non-static inner classes take via constructor.

Jackson 1.9 will actually supports deserialization of simple uses of non-static inner classes, see this Jira entry.