Jackson如何将json反序列化为泛型类型?

Jar*_*vis 3 java generics jackson deserialization

类人:

@Data
public class Person<T extends Parent> implements Serializable {
    private static final long serialVersionUID = 7822965786010192978L;

    private static final ObjectMapper objectMapper = new ObjectMapper();  
    private String id;    
    private T people; // change (String peopleInfo) to object extends Parent after read data from database
    private String peopleInfo; // change (T people) to string and save in the dataBase as an string

    @SneakyThrows
    public void setPeople(T people) {
        this.people = people;
        peopleInfo = objectMapper.writeValueAsString(people);
    }

    @SneakyThrows
    public void setPeopleInfo(String peopleInfo) {
        this.peopleInfo = peopleInfo;
        if (!Strings.isNullOrEmpty(peopleInfo)) {
            people = objectMapper.readValue(peopleInfo, new TypeReference<T>() {});
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

班级家长:

@Data
public class Parent implements Serializable {
    private static final long serialVersionUID = 2092353331893381153L;
    private String name;
}
Run Code Online (Sandbox Code Playgroud)

班级儿童:

@Data
public class Child extends Parent {
    private static final long serialVersionUID = 3318503314202792570L;
    private String pocketMoney;
}
Run Code Online (Sandbox Code Playgroud)

和测试功能:我想将其保存persnInfo到数据库中,String并在从数据库读取数据后自动将其更改string为对象people。

@Test
public void testReadData() throws Exception {
    Child child = new Child();
    child.setName("_child");
    child.setPocketMoney("10$");

    Person<Child> person = new Person<>();
    person.setId("1");
    person.setPeople(child);

    // assume this json was read from database
    String json = person.getPeopleInfo();
    System.out.println(json);

    Person<Child> readPerson = new Person<>();
    readPerson.setId("1");
    readPerson.setPeopleInfo(json);

    Child readChild = readPerson.getPeople();
    System.out.println(readChild.getPocketMoney());
}
Run Code Online (Sandbox Code Playgroud)

错误发生了:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“pocketMoney”(类pers.test.common.objmapper.Parent),未标记为可忽略(一个已知属性:“name”])

[来源:{"name":"_child","pocketMoney":"10$"}; 行:1,列:33](通过参考链:pers.test.common.objmapper.Parent[“pocketMoney”])

在 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)

我不知道如何解决这个问题,任何人都可以帮助我在不改变testReadData()' but change the model人民的情况下解决这个问题。

Gho*_*ica 5

你的问题在这里:

new TypeReference<T>()
Run Code Online (Sandbox Code Playgroud)

这不会执行您期望的操作。Java 泛型在运行时被擦除;所以上面的说法基本上是new TypeReference<Object>。

换句话说 - 你声明的事实

Person<Child> readPerson = new Person<>();
Run Code Online (Sandbox Code Playgroud)

仅仅期望Child 对象是不够的!

您可能必须将特定的类传递Child.class给映射回 JSON 字符串的代码。欲了解更多信息,请查看此处。