2019年/11月/04日
常用json lib对比
我们常用来处理的json库有gson,jackson,fastjson,simple json,他们各自在处理json的反序列化的时候有重大的差异
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
对于json-simple因为api太简单了,实用性不好
String json = JSONValue.toJSONString(obj);
Object obj = JSONValue.parse(JSON.toJSONString(obj));
对于对象序列化到json完全不支持java的自定义类型
我们主要看gson,jackson,fastjson
基础数据
public class User {
private String name = "hello";
private Date date = new Date();
private byte[] bytes = "hello".getBytes();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
}
User user = new User();
List<User> users = Arrays.asList(user);
List list = new ArrayList();
list.add(1);
list.add(new BigInteger("13323234242444444444444"));
list.add(1.0);
list.add(new BigDecimal("22355555555555555555555555555555555555555.3255555555555550005"));
list.add("hello");
list.add(null);
list.add(true);
list.add(false);
list.add(user);
list.add(users);
fast json
for (Object obj : list) {
System.out.print(JSON.toJSONString(obj));
System.out.print(" => ");
Object parse = JSON.parse(JSON.toJSONString(obj));
if (parse != null) {
System.out.println(parse.getClass());
} else {
System.out.println();
}
}
1 => class java.lang.Integer
13323234242444444444444 => class java.math.BigInteger
1.0 => class java.math.BigDecimal
22355555555555555555555555555555555555555.3255555555555550005 => class java.math.BigDecimal
"hello" => class java.lang.String
null =>
true => class java.lang.Boolean
false => class java.lang.Boolean
{"bytes":"aGVsbG8=","date":1573560286315,"name":"hello"} => class com.alibaba.fastjson.JSONObject
[{"bytes":"aGVsbG8=","date":1573560286315,"name":"hello"}] => class com.alibaba.fastjson.JSONArray
Gson
Gson gson = new Gson();
for (Object obj : list) {
System.out.print(gson.toJson(obj));
System.out.print(" => ");
Object o = gson.fromJson(gson.toJson(obj), Object.class);
if (o != null) {
System.out.println(o.getClass());
} else {
System.out.println();
}
}
1 => class java.lang.Double
13323234242444444444444 => class java.lang.Double
1.0 => class java.lang.Double
22355555555555555555555555555555555555555.3255555555555550005 => class java.lang.Double
"hello" => class java.lang.String
null =>
true => class java.lang.Boolean
false => class java.lang.Boolean
{"name":"hello","date":"Nov 12, 2019 8:04:46 PM","bytes":[104,101,108,108,111]} => class com.google.gson.internal.LinkedTreeMap
[{"name":"hello","date":"Nov 12, 2019 8:04:46 PM","bytes":[104,101,108,108,111]}] => class java.util.ArrayList
Jackson
ObjectMapper mapper = new ObjectMapper();
for (Object obj : list) {
System.out.print(mapper.writeValueAsString(obj));
System.out.print(" => ");
Object o = mapper.readValue(mapper.writeValueAsString(obj), Object.class);
if (o != null) {
System.out.println(o.getClass());
} else {
System.out.println();
}
}
1 => class java.lang.Integer
13323234242444444444444 => class java.math.BigInteger
1.0 => class java.lang.Double
22355555555555555555555555555555555555555.3255555555555550005 => class java.lang.Double
"hello" => class java.lang.String
null =>
true => class java.lang.Boolean
false => class java.lang.Boolean
{"name":"hello","date":1573560286315,"bytes":"aGVsbG8="} => class java.util.LinkedHashMap
[{"name":"hello","date":1573560286315,"bytes":"aGVsbG8="}] => class java.util.ArrayList
总结
- 关于json里小数和整数问题,fastjson和jackson都选择了进行猜测,fastjson更彻底,把小数转成了BigDecimal
- JSON,Gson,ObjectMapper都是线程安全的
- 对于byte[],fastjson和jackson都选择了base64编码
- Gson把数字全部用double表示,对于时间默认格式化了
- Jackson居然还要抛出受检异常,这个api设计太失败了
- 总体上来说还是Fastjson的api易用