【问题标题】:How does Jackson deserialize json into a generic type?Jackson 如何将 json 反序列化为泛型类型?
【发布时间】:2017-12-23 00:13:57
【问题描述】:

类人:

@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>() {});
        }
    }
}

班级家长:

@Data
public class Parent implements Serializable {
    private static final long serialVersionUID = 2092353331893381153L;
    private String name;
}

类孩子:

@Data
public class Child extends Parent {
    private static final long serialVersionUID = 3318503314202792570L;
    private String pocketMoney;
}

和测试功能:我想将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());
}

发生错误:

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

在 [来源:{"name":"_child","pocketMoney":"10$"}; line: 1, column: 33](通过引用链:pers.test.common.objmapper.Parent["pocketMoney"])

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

我不知道如何解决这个问题,任何人都可以在不更改 testReadData()' but change the modelPeople` 的情况下帮助我让它通过。

【问题讨论】:

  • @GhostCat 在Person.setPeopleInfo () people = objectMapper.readValue(peopleInfo, new TypeReference&lt;T&gt;() {});

标签: java generics jackson deserialization


【解决方案1】:

你的问题在这里:

new TypeReference<T>()

这并不符合您的预期。 Java 泛型在运行时被擦除;因此上面的语句基本上是new TypeReference&lt;Object&gt;

换句话说 - 你声明的事实

Person<Child> readPerson = new Person<>();

expect 子对象根本不够!

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

【讨论】:

  • 我知道通过测试很有趣:ObjectMapper objectMapper = new ObjectMapper(); Child readChild = objectMapper.readValue(readPerson.getPeopleInfo(), Child.class); 这会起作用,但我仍然想动态地在 pojo People self 中进行。
  • 如前所述:那么您必须以某种方式传递特定类型,例如 Child.class。这就是我添加第二个链接的原因!
  • 我确实这么认为。如果我弄错了,并且有人有一个更好的 解决方案(我对此表示怀疑,因为如前所述:那些泛型类型在运行时被擦除) - 请随意接受另一个答案。
猜你喜欢
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
  • 2014-04-05
  • 2012-10-18
  • 1970-01-01
  • 2012-07-24
相关资源
最近更新 更多