記一次FastJSON和Jackson解析json時遇到的中括號問題
阿新 • • 發佈:2018-11-28
follow rac blog com known ast 文章 驗證 oid
版權聲明:本文為博主原創文章,未經博主同意不得轉載。 https://blog.csdn.net/jadyer/article/details/24395015
以下是生成json和解析json的代碼
接下來描寫敘述下遇到的問題
但在解析時。FastJSON會報以下的異常
Jackson會報以下的異常
個人感覺Jackson的異常看上去更直觀,可能是二者內部的驗證邏輯不同導致的
完整版見https://jadyer.github.io/
先列出來正確的解析代碼,接著再描寫敘述問題詳情。
首先是用到的JavaBean
package com.jadyer.model; public class User { private String name; private Book book; public String getName() { return name; } public void setName(String name) { this.name = name; } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } }
package com.jadyer.model; public class Book { private String name; // private List<Author> author = new ArrayList<Author>(); private Author author; public String getName() { return name; } public void setName(String name) { this.name = name; } // public List<Author> getAuthor() { // return author; // } // public void setAuthor(List<Author> author) { // this.author = author; // } public Author getAuthor() { return author; } public void setAuthor(Author author) { this.author = author; } }
package com.jadyer.model; public class Author { private String name; private int money; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } }
以下是生成json和解析json的代碼
package com.jadyer.main;
import java.io.IOException;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import com.alibaba.fastjson.JSON;
import com.jadyer.model.User;
public class JSONDemo {
// /**
// * 生成{"book":{"author":[{"money":500,"name":"南派三叔"},{"money":200,"name":"孔二狗"}],"name":"網絡文學"},"name":"玄玉"}
// */
// private static String format(){
// List<Author> authorList = new ArrayList<Author>();
// Author author11 = new Author();
// author11.setName("南派三叔");
// author11.setMoney(500);
// authorList.add(author11);
// Author author22 = new Author();
// author22.setName("孔二狗");
// author22.setMoney(200);
// authorList.add(author22);
// Book book = new Book();
// book.setName("網絡文學");
// book.setAuthor(authorList);
// User user = new User();
// user.setName("玄玉");
// user.setBook(book);
// return JSON.toJSONString(user);
// }
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
String jsonText = "{\"book\":{\"author\":{\"money\":500,\"name\":\"南派三叔\"},\"name\":\"網絡文學\"},\"name\":\"玄玉\"}";
//用到的jar為fastjson-1.1.36.jar
User userFromFastJSON = JSON.parseObject(jsonText, User.class);
System.out.println(ReflectionToStringBuilder.toString(userFromFastJSON.getBook().getAuthor(), ToStringStyle.MULTI_LINE_STYLE));
System.out.println("----------------------------------------------------------------------------------");
//用到的jar為jackson-all-1.9.11.jar
User userFromJackson = new ObjectMapper().readValue(jsonText, User.class);
System.out.println(ReflectionToStringBuilder.toString(userFromJackson.getBook().getAuthor(), ToStringStyle.MULTI_LINE_STYLE));
}
}
接下來描寫敘述下遇到的問題
//上面解析正常時用到的json串
//"{\"book\":{\"author\":{\"money\":500,\"name\":\"南派三叔\"},\"name\":\"網絡文學\"},\"name\":\"玄玉\"}";
//我在用fastjson和jackson解析時都會報錯時用的json串
//"{\"book\":{\"author\":[{\"money\":500,\"name\":\"南派三叔\"}],\"name\":\"網絡文學\"},\"name\":\"玄玉\"}";
//它倆的差別在於:book中僅僅有一個author對象,僅僅是多加了[],但其仍為合法的json串
//而且http://tool.oschina.net/codeformat/json均驗證通過
但在解析時。FastJSON會報以下的異常
Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error, expect {, actual ], pos 39
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:212)
at com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer.parseRest(ASMJavaBeanDeserializer.java:96)
at Fastjson_ASM_User_1.deserialze(Unknown Source)
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:513)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:244)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:220)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:179)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:323)
at com.jadyer.main.JSONDemoDetail.main(JSONDemoDetail.java:18)
Jackson會報以下的異常
Exception in thread "main" org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.jadyer.model.Author out of START_ARRAY token
at [Source: java.io.StringReader@509ced8e; line: 1, column: 10] (through reference chain: com.jadyer.model.User["book"]->com.jadyer.model.Book["author"])
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:219)
at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:212)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromArray(BeanDeserializer.java:875)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:597)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1863)
at com.jadyer.main.JSONDemoDetail.main(JSONDemoDetail.java:22)
個人感覺Jackson的異常看上去更直觀,可能是二者內部的驗證邏輯不同導致的
只是還是傾向於FastJSON,即便一時之間沒看明確它的異常描寫敘述。但那也僅僅是這方面的經驗不足而已
以下說一下解決的方法:Book.java中將author改動為List<Author>類型的屬性。並加入相應的setter和getter就可以
個人的理解是:FastJSON和Jackson解析json為JavaBean時,先查看實體類的相應屬性
當發現該屬性不能承載多個對象值,且json串中恰好該屬性使用的是中括號。這並非它預期的大括號,於是報錯了
記一次FastJSON和Jackson解析json時遇到的中括號問題