Jackson IOException: не удается десериализовать класс com.mycompany.models.Person $Address (тип нестатического класса членов) как Bean
У меня есть класс, который выглядит так:
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
}
и heres, как я использую джексон с ним.
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!!!
}
}
3-я строка основного метода (где я пытаюсь преобразовать json в объект Person), выдает это исключение:
IOException: Can not deserialize Class com.mycompany.models.Person$Address (of type non-static member class) as a Bean
что я делаю неправильно?
Ответы
Ответ 1
Поскольку внутренние классы не имеют конструктора с нулевым аргументом по умолчанию (у них есть скрытая ссылка на внешний/родительский класс), Джексон не может их создать.
Решение состоит в том, чтобы использовать внутренние классы static
:
public class Outer {
static class Inner {
private String foo;
public String getFoo() { return foo; }
}
}
Оригинальный ответ:
Есть некоторые проблемы в реализации, и кажется, что вы не можете сериализовать такие классы, см. cowtowncoder для деталей.
Ответ 2
Правильно, это было то, что вы не можете сделать с текущими версиями Джексона (1.8 и ранее).
Но абсолютно необходимо, чтобы внутренний класс был нестационарным? Если нет, просто добавьте "статический" в объявление адреса, и он будет работать нормально; проблема заключается в "скрытом" этом указателе, который нестатические внутренние классы принимают через конструктор.
Jackson 1.9 фактически поддерживает десериализацию простых применений нестатических внутренних классов, см. эту запись в Jira.