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


    版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/jadyer/article/details/24395015

    完整版见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串中恰好该属性使用的是中括号。这并非它预期的大括号,于是报错了

  • 相关阅读:
    JVM内存模型与类加载机制
    JS 实现动态轮播图
    Jedis & spring-data-redis
    JAVA反射机制与动态代理
    JavaScript -- 筑基
    IO流与装饰者模式
    ES&IK环境搭建
    Elasticsearch笔记
    DQL
    DDL--DML
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10034445.html
Copyright © 2020-2023  润新知