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

原文地址:https://www.cnblogs.com/ldxsuanfa/p/10034445.html