java - 使用 Jackson 和 Json 时出错

标签 java json jackson

我正在尝试解析一些 JSON(JSON 的完整示例可以在 this Gist 中看到)。我在下面展示了 JSON 的一般结构:

[
    {
        "title": "Principles of Compiler Design",
        "authors": [
            "Aho",
            "Ullman"
        ],
        "publisher": "Addison Wesley",
        "year": 1977
    },
    {
        "title": "Compilers: Principles Techniques and Tools",
        "authors": [
            "Aho",
            "Sethi",
            "Ullman"
        ],
        "publisher": "Addison Wesley",
        "year": 1985
    }
]

我正在尝试使用 Jackson 库解析 JSON,但在测试时出现以下错误:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
 at [Source: library.json; line: 2, column: 49] (through reference chain: com.acme.datatypes.User["authors"])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:163)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:588)
    at com.fasterxml.jackson.databind.deser.std.JdkDeserializers$StringDeserializer.deserialize(JdkDeserializers.java:90)
    at com.fasterxml.jackson.databind.deser.std.JdkDeserializers$StringDeserializer.deserialize(JdkDeserializers.java:59)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:336)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:89)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:290)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2563)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1759)
    at com.acme.datatypes.UserTest.main(UserTest.java:20)

这是我的代码:

用户测试类:

public class UserTest {
    public static void main(String[] args) throws JsonParseException,
            JsonMappingException, IOException {
        File jsonFile = new File("library.json");

        User user = null;

        ObjectMapper mapper = new ObjectMapper();

        user = mapper.readValue(jsonFile, User.class);
        System.out.println(user.getTitle());

        user = mapper.readValue(jsonFile, User.class);
        System.out.println(user.getAuthors());

        user = mapper.readValue(jsonFile, User.class);
        System.out.println(user.getPublisher());

        user = mapper.readValue(jsonFile, User.class);
        System.out.println(user.getYear());
    }
}

用户类:

public class User {

    private String authors;
    private String publisher;
    private String title;
    private Number year;

    public String getAuthors() {
        return this.authors;
    }

    public void setAuthors(String authors) {
        this.authors = authors;
    }

    public String getPublisher() {
        return this.publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Number getYear() {
        return this.year;
    }

    public void setYear(Number year) {
        this.year = year;
    }
}

有人知道问题出在哪里吗?谢谢。

最佳答案

两件事:

  1. 您的用户类正在定义 authors作为字符串的属性。但在 JSON 中它是一个数组,因此您需要在 Java 对象中使用集合或数组类型。像这样的东西:

    private List<String> authors

  2. 您在测试类中反复解析 JSON 文件。您只需要解析一次,并且需要使用父类(super class)型标记,因为 JSON 中有一个项目列表(不仅仅是一个)。您还使用了错误的类型来反序列化 (User.class)。而不是所有这些行:

    user = mapper.readValue(jsonFile, User.class); System.out.println(user.getTitle());

    user = mapper.readValue(jsonFile, User.class); // <-- unnecessary parsing System.out.println(user.getAuthors());

    user = mapper.readValue(jsonFile, User.class); // <-- unnecessary parsing System.out.println(user.getPublisher());

    user = mapper.readValue(jsonFile, User.class); // <-- unnecessary parsing System.out.println(user.getYear());

只需使用:

List<User> userList =
    mapper.readValue(jsonFile, new TypeReference<List<User>>() {});

一旦您获得测试类中的用户列表,您就可以使用增强的 for 循环迭代它们。

for(User user : userList) {
    System.out.println(user.getTitle());
}

关于java - 使用 Jackson 和 Json 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15251010/

相关文章:

java - 如何获得默认的日期和时间格式模式

java - 如何在 java 中读取/写入 excel 复选框状态

java - 登录logback时如何处理disk full错误?

jackson - 如何在 Jackson 中订购哈希集? @JsonPropertyOrder 不起作用

java - 定制 Jackson 反序列化器来处理任何 bean 的属性

java - 使用时区java将字符串转换为适当的日期

javascript - 使用 JSON Web token 和 node.js/express 保护 URL 的正确方法

javascript - 无法调用未定义的 GetJson 的方法 'toLowerCase'

java - Jackson 在一个 POJO 中反序列化两个不同的 Json 表示

Javascript 循环推送函数