2013-03-06 93 views
11

我想解析一些JSON(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 
    } 
] 

我想與傑克遜庫解析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; 
    } 
} 

有誰知道這個問題可能是什麼?謝謝。

+0

可以共享java代碼也,你需要將其轉換爲一個列表 – 2013-03-06 15:17:43

+0

你怎麼宣佈你'authors'財產?它應該是一個集合或數組類型。 – Perception 2013-03-06 15:25:05

+0

@Arun P Johny,我編輯了文檔並添加了代碼,以供您參閱 – tribrick 2013-03-06 17:59:20

回答

15

兩個快速件事:

  1. 您的用戶類定義authors屬性爲一個字符串。但是在JSON中它是一個數組,因此您需要在Java對象中使用集合或數組類型。喜歡的東西:

    private List<String> authors

  2. 您反覆分析你的測試類的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()); 
} 
+1

它很明顯,但即時得到這個錯誤現在:線程「主」的異常com.fasterxml.jackson.core.JsonParseException:在ARRAY條目之內/之間意外的輸入結束 at [Source :library.json; line:11,column:200] – tribrick 2013-03-06 18:29:27

+0

@tribrick - 將你的JSON文件的內容轉儲到[jsonlint](http://jsonlint.com)中,並驗證它是格式良好的。 – Perception 2013-03-06 18:30:51

+0

是的,這是一個有效的JSON文件 – tribrick 2013-03-06 18:35:35

4

由於您使用數組,你需要將其轉換成一個數組或列表

由於陣列

MyClass[] myObjects = mapper.readValue(json, MyClass[].class); 

方式列表

List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){}); 

用戶

public class User { 

    private List<String> authors; 
    private String publisher; 
    private String title; 
    private Number year; 

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

    public void setAuthors(List<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; 
    } 
} 

用法:

List<User> l = mapper.readValue(new File(""),new TypeReference<List<User>>() {});