使用Jackson和Json时出错 - java

我正在尝试解析一些JSON(可以在this Gist中看到JSON的完整示例)。我在下面显示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;
    }
}

有谁知道可能是什么问题?谢谢。

参考方案

两件事:

  • 您的User类正在将authors属性定义为String。但是在JSON中,它是一个数组,因此您需要在Java对象中使用集合或数组类型。就像是:
    private List<String> authors
  • 您反复分析测试类中的JSON文件。您只需要解析一次,并且需要使用超类型令牌,因为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-搜索字符串数组中的字符串 - java

    在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…

    Jackson:使用不同的属性名称序列化/反序列化 - java

    我有这个POJO:public class SetPoint { private String tagName; //more fields //getters and setters } 我从REST API获取SetPoints,对它们进行处理,然后再次发送。问题是我想从JSON反序列化SetPoint,例如:{ "tagnameOpc…

    Java Globbing模式以匹配目录和文件 - java

    我正在使用递归函数遍历根目录下的文件。我只想提取*.txt文件,但不想排除目录。现在,我的代码如下所示:val stream = Files.newDirectoryStream(head, "*.txt") 但是这样做将不会匹配任何目录,并且返回的iterator()是False。我使用的是Mac,所以我不想包含的噪音文件是.DS_ST…

    Java RegEx中的单词边界\ b - java

    我在使用\b作为Java Regex中的单词定界符时遇到困难。对于text = "/* sql statement */ INSERT INTO someTable"; Pattern.compile("(?i)\binsert\b");找不到匹配项Pattern insPtrn = Pattern.compile(&…

    移至上一级目录 - java

    是否可以将目录下移到Java下一级?例如在命令提示符下:C:\Users\foo\ 我可以使用cd..转到:C:\Users\ 是否可以在Java中执行此操作,因为我正在使用System.getProperty(“ user.dir”);获得目录。但是,这不是我要使用的目录,而是目录的下一级。我已经考虑过使用Path类方法; subpath(i,j),但是如…