• 热门专题

记一次FastJSON和Jackson解析json时遇到的中括号问题

作者:  发布日期:2014-04-24 20:38:26
Tag标签:问题  
  • 先列出来正确的解析代码,接着再描述问题详情。

    首先是用到的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串中恰好该属性使用的是中括号,这并不是它预期的大括号,于是报错了

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规