json相关类库,java对象与json相互转换
有效选择七个关于Java的JSON开源类库
转自:http://www.open-open.com/lib/view/open1397870197828.html
翻译:
(英语原文:http://www.developer.com/lang/jscript/top-7-open-source-json-binding-providers-available-today.html)
简介
JSON是JavaScript Object Notation的缩写,是一种轻量级的数据交换形式,是一种XML的替代方案,而且比XML更小,更快而且更易于解析。因为JSON描述对象的时候使用的是JavaScript语法,它是语言和平台独立的,并且这些年许多JSON的解析器和类库被开发出来。在这篇文章中,我们将会展示7种Java JSON类库。基本上,我们将会试着把Java对象转换JSON格式并且存储到文件,并且反向操作,读JSON文件转换成一个对象。为了让文章更有意义,我们将会测量每一种JSON类库在不同情况下的处理速度。
(一)类库介绍及其使用
(1)使用Jackson类库
第一个介绍的是Jackson类库,Jackson库是一个“旨在为开发者提供更快,更正确,更轻量级,更符合人性思维” 的类库。Jackson为处理JSON格式提供了三种模型的处理方法。
1、流式API或者增量解析/产生( incremental parsing/generation):读写JSON内容被作为离散的事件。
2、树模型:提供一个可变内存树表示JSON文档。
3、数据绑定(Data binding):实现JSON与POJO(简单的Java对象(Plain Old Java Object))的转换
我们感兴趣的是Java对象与JSON的转换,因此,我们将集中于第三种处理方法。首先我们 需要下载Jackson。Jackson的核心功能使用三个类库,分别是jackson-core-2.3.1, jackson-databind- 2.3.1和jackson-annotations-2.3.1; 三个类库的下载都来自于Maven仓库,给出地址:
http://repo1.maven.org/maven2/com/fasterxml/jackson/
(译者注:在http://repo1.maven.org/maven2/com/fasterxml/jackson/core/中,正好是三个类库的文件夹)
现在,让我们来工作吧,为了从Java对象中获得一个一个复杂的JSON对象,我们将会使用下面的类去构造一个对象。同样的Java对象将会被用于这篇文章的所有的类库中。
public class JsonThirdObject {
private int age = 81;
private String name = "Michael Caine";
private List<String> messages;
public JsonThirdObject() {
this.messages = new ArrayList<String>() {
{
add("You wouldn't hit a man with no trousers..");
add("At this point, I'd set you up with a..");
add("You know, your bobby dangler, giggle stick,..");
}
};
}
// Getter and setter
}
public class JsonSecondObject {
private int age = 83;
private String name = "Clint Eastwood";
private JsonThirdObject jsnTO = new JsonThirdObject();
private List<String> messages;
public JsonSecondObject() {
this.messages = new ArrayList<String>() {
{
add("This is the AK-47 assault..");
add("Are you feeling lucky..");
add("When a naked man's chasing a..");
}
};
}
// Getter and setter
}
public class JsonFirstObject {
private int age = 76;
private String name = "Morgan Freeman";
private JsonSecondObject jsnSO = new JsonSecondObject();
private List<String> messages;
public JsonFirstObject() {
this.messages = new ArrayList<String>() {
{
add("I once heard a wise man say..");
add("Well, what is it today? More..");
add("Bruce... I'm God. Circumstances have..");
}
};
}
// Getter and setter
}
public class Json {
private int age = 52;
private String name = "Jim Carrey";
private JsonFirstObject jsnFO = new JsonFirstObject();
private List<String> messages;
public Json() {
this.messages = new ArrayList<String>() {
{
add("Hey, maybe I will give you..");
add("Excuse me, I'd like to..");
add("Brain freeze. Alrighty Then I just..");
}
};
}
// Getter and setter
}
上面的Java对象转换成JSON格式是下面这样的。
{
"age":52,
"name":"Jim Carrey",
"jsnFO":{
"age":76,
"name":"Morgan Freeman",
"jsnSO":{
"age":83,
"name":"Clint Eastwood",
"jsnTO":{
"age":81,
"name":"Michael Caine",
"messages":[
"You wouldn't hit a man..",
"At this point, I'd set you..",
"You know, your bobby dangler.."
]
},
"messages":[
"This is the AK-47 assault..",
"Are you feeling lucky..",
"When a naked man's chasing a.."
]
},
"messages":[
"I once heard a wise man..",
"Well, what is it today? More..",
"Bruce... I'm God. Circumstances have.."
]
},
"messages":[
"Hey, maybe I will give you a call..",
"Excuse me, I'd like to ask you a few..",
"Brain freeze. Alrighty Then I just heard.."
]
}
现在,让我们来看看怎么样把Java对象转换成JSON并且写入文件。Jackson使用一个ObjectMapper功能,我们第一步要做的是:
Json jsonObj = new Json(); ObjectMapper mapper = new ObjectMapper();
然后,我们将会使用这个ObjectMapper直接写入值到文件。
System.out.println("Convert Java object to JSON format and save to file");
try {
mapper.writeValue(new File("c:\\jackson.json"), jsonObj);
} catch (JsonGenerationException e) {
} catch (JsonMappingException e) {
} catch (IOException e) {
}
现在,我们有了一个JSON文件,但是,怎么样转回Java对象呢?我们可以这样做:
System.out.println("Read JSON from file, convert JSON back to object");
try {
jsonObj = mapper.readValue(new File("c:\\jackson.json"), Json.class);
} catch (JsonGenerationException e) {
} catch (JsonMappingException e) {
} catch (IOException e) {
}
从上面的例子我们知道了JSON和Java对象的相互转换,在try-catch中总共也就两行,看起来不错是吧,但是它快么?我们将会在后面的文章中揭晓。
(2)使用 Google-Gson类库
第二种就是 Google-Gson,我们立即开始讨论 Gson,你或许更喜欢他的全名Google-Gson。Gson能实现Java对象和JSON之间的相互转换。甚至都不需要注释。Gson的特点:
1)提供简单的toJson()方法和fromJson()去实现相互转换。
2)可以从JSON中转换出之前存在的不可改变的对象。
3)扩展提供了Java泛型。
4)支持任意复杂的对象。
Gson就需要一个.jar文件,gson-2.2.4.jar,可以通过http://code.google.com/p/google-gson/downloads/list下载。下面是例子,把Java对象转换成JSON。
Json jsonObj = new Json();
Gson gson = new Gson();
System.out.println("Convert Java object to JSON format and save to file");
try (FileWriter writer = new FileWriter("c:\\gson.json")) {
writer.write(gson.toJson(jsonObj));
} catch (IOException e) {
}
JSON转换成Java对象:
System.out.println("Read JSON from file, convert JSON string back to object");
try (BufferedReader reader = new BufferedReader(new FileReader("c:\\gson.json"))) {
jsonObj = gson.fromJson(reader, Json.class);
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
上面就是我们所有需要做的,接下来我们可以对 jsonObj 作进一步处理。当调用JSON操作的时候,因为Gson的实例化对象没有维持任何状态,我们可以重复使用一个对象为多个JSON序列化和反序列化操作。
(3)使用JSON-lib类库
JSON-lib类库是基于Douglas Crockford的工作成果,能转换bean,map,集合(collection),java数组和XML转换成JSON并能反向转换成beans和动态bean(DynaBean)。JSON-lib类库的下载地址:http://sourceforge.net/projects/json-lib/files/ 下面这些是依赖文件
· jakarta commons-beanutils 1.9.1
· jakarta commons-collections 3.2.1
· jakarta commons-logging 1.1.3
(译者注:Douglas Crockford是Web开发领域最知名的技术权威之一,ECMA JavaScript2.0标准化委员会委员。被JavaScript之父Brendan Eich称为JavaScript的大宗师(Yoda)。曾任Yahoo!资深JavaScript架构师,现任PayPal高级JavaScript架构师。他是JSON、JSLint、JSMin和ADSafe的创造者,也是名著《JavaScript: The Good Parts》(中文版《JavaScript语言精粹》)的作者。撰写了许多广为流传、影响深远的技术文章,包括“JavaScript:世界上最被误解的语言”。Douglas Crockford曾在著名的Lucasfilm电影公司任技术总监;在Paramount(派拉蒙)公司任新媒体高级总监;communities社区创始人兼CEO;State软件公司CTO。2012.05.14,Paypal宣布Douglas Crockford加入Paypal。)
同样,让我们来把Java对象转成JSON。
Json jsonObj = new Json();
JSONObject json;
System.out.println("Convert Java object to JSON format and save to file");
try (FileWriter writer = new FileWriter("c:\\json-lib.json")) {
json = JSONObject.fromObject(jsonObj);
json.write(writer);
} catch (IOException e) {
}
JSON转Java对象
System.out.println("Read JSON from file, convert JSON string back to object");
try (BufferedReader reader = new BufferedReader(new FileReader("c:\\json-lib.json"))) {
jsonObj = (Json) JSONObject.toBean(JSONObject.fromObject(reader), Json.class);
} catch (IOException ex) {
}
这里有个问题,这些依赖关系会影响到性能吗?文章在下面揭晓。
(4)使用Flexjson类库
Flexjson是 一个轻量级的库,能序列化和反序列化Java对象和JSON,允许深层和浅层对象的拷贝。深度拷贝意味着一个被Flexjson序列化的对象,它能让对象 做到类似于延迟加载(lazy-loading)的技术,能让我们在对对象有需要时才提取。当我们想把整个对象写入到文件时,这不是一个好的情况,但是它 知道需要才去做时,这是很好的。
Flexjson下载地址:http://sourceforge.net/projects/flexjson/files/ 它不需要其他库就可以工作。下面是例子:Java对象转JSON。
Json jsonObj = new Json();
JSONSerializer serializer = new JSONSerializer();
System.out.println("Convert Java object to JSON format and save to file");
try (FileWriter writer = new FileWriter("c:\\flexjson.json")) {
serializer.deepSerialize(jsonObj, writer);
} catch (IOException e) {
}
JSON转Java对象
System.out.println("Read JSON from file, convert JSON string back to object");
try (BufferedReader reader = new BufferedReader(new FileReader("c:\\flexjson.json"))){
jsonObj = new JSONDeserializer<Json>().deserialize(reader);
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
简单有效是吧!
(5)使用Json-io类库
json-io有 两个主要的类,一个读和一个写,排除了使用ObjectInputStream和 ObjectOutputStream两个类去读写。Json-io能 序列化任意的Java对象图(graph)转变成JSON,并且能记忆完整的语义图(graph semantics)和对象类型。下载地址: Maven Central Repository
它不需要其他依赖。
例子:Java对象转JSON
Json jsonObj = new Json();
System.out.println("Convert Java object to JSON format and save to file");
try (JsonWriter writer = new JsonWriter(new FileOutputStream("c:\\json-io.json"))){
writer.write(jsonObj);
} catch (IOException e) {
}
JSON转Java对象
System.out.println("Read JSON from file, convert JSON string back to object");
try (JsonReader reader = new JsonReader(new FileInputStream(new File("c:\\json-io.json")))) {
jsonObj = (Json) reader.readObject();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
它的文档上说,Json-io比JDK的ObjectInputStream 和ObjectOutputStream的序列化操作要快,我们将会在后面的文章中说明。
(6)使用Genson类库
Genson是一个可扩展的,可伸缩的,易于使用的开源库。除此之外,Genson完整支持了泛型,支持JSON在JAX-RS的实现,支持JAXB的注释(annotation)和类型(types),并且允许序列化和反序列化拥有复杂关键字的map。
下载地址:http://code.google.com/p/genson/downloads/list ,它没有任何依赖。
例子:Java对象转JSON
Json jsonObj = new Json();
Genson genson = new Genson();
System.out.println("Convert Java object to JSON format and save to file");
try (FileWriter writer = new FileWriter("c:\\genson.json")) {
writer.write(genson.serialize(jsonObj));
} catch (IOException | TransformationException e) {
}
JSON转Java对象
System.out.println("Read JSON from file, convert JSON string back to object");
try (BufferedReader reader = new BufferedReader(new FileReader("c:\\genson.json"))) {
jsonObj = genson.deserialize(reader, Json.class);
} catch (FileNotFoundException e) {
} catch (IOException | TransformationException e) {
}
(7)使用JSONiJ类库
最后一个讨论的是JSONiJ。JSONiJ是JSON的解析器,一个JPath和Marshaller的实现,能实现Java对象和JSON的相互转换。下载地址:https://bitbucket.org/jmarsden/jsonij/downloads
它不需要任何依赖。
例子:Java对象转JSON
Json jsonObj = new Json();
System.out.println("Convert Java object to JSON format and save to file");
try (FileWriter writer = new FileWriter("c:\\jsonij.json")) {
writer.write(JSONMarshaler.marshalObject(jsonObj).toJSON());
} catch (IOException | JSONMarshalerException e) {
}
JSON转Java 对象
System.out.println("Read JSON from file, convert JSON string back to object");
try (BufferedReader reader = new BufferedReader(new FileReader("c:\\jsonij.json"))) {
JSON json = JSON.parse(reader);
// Now we need to parse the JSONObject object and put values back
// to our Json object
for (Field field : jsonObj.getClass().getDeclaredFields()) {
try {
field.setAccessible(true);
field.set(field.getName(), json.get(field.getName()));
} catch (IllegalArgumentException | IllegalAccessException e) {
}
}
} catch (FileNotFoundException e) {
} catch (IOException | ParserException e) {
}
看起来JSONiJ需要的代码多些,性能怎么样,我们看下面。
(二)基准测试
现在我们要来看看性能了,测试硬件配置:Intel Core i5 laptop with 2.50GHz 单通道DDR3 RAM 4G,软件配置:Windows 7 Ultimate 64-bit SP1
基准测试运行一样的虚拟机(JVM),在测试之前,每一个类库都有一个热身,去限制内存使用的造成的影响,用一个显式调用垃圾收集器。下面的图表代表的是序列化和反序列化JSON数据以毫秒级使用50次迭代和10次热身(warm-up)迭代的平均的时间。
(译者注:红色为序列化(Java对象转JSON),蓝色为反序列化(JSON转Java对象))

上面的图表显示,Flexjson序列化小数据时是最快的,而JSON-lib是最慢的。反序列化的时候,Gson最快,JSON-lib还是最慢的。
下面的图表代表的是我们的数据在287kb时,序列化和反序列化所花费的平均时间。

这张图显示,我们对少量的数据操作时,最快的是Gson ,之后的是 Genson和Flexjson。
当变成大数据时,结果变得很不一样。在下面的图表中,使用的是108Mb的数据,在序列化的时候,Jackson变成了最快的,Flexjson变成第二快。在反序列化的时候,JSON-lib变成了最快的,之前在处理小数据时,它是最慢的,第二快的是Jackson。

下面的图表,显示的是处理更大一点的数据时,我们应该使用Jackson和JSON-lib。

另外一个重要的测试是关于.jar包的大小。这对于移动端的开发很重要,我们从下图中看到,json-io最小,之后依次是Flexjson和JSONiJ:

(三)结论
在这篇文章中,我们知道了七种方式来实现Java对象和JSON之间的互相转换。以及哪一个类库更快,哪一个更慢,在什么情况下使用等。作为结论, 如果你在你的应用中是想使用小一点的数据量,你应该使用Flexjson或者Gson,如果你需要大的数据量你应该考虑Jackson 和JSON- lib。
json相关类库,java对象与json相互转换的更多相关文章
- json字符串转java对象,json中字段名称与对象属性名称不一致
json字符串转java对象,json字段名称与对象属性名称不一致可以在对象属性上添加注解@SerializedName解决
- 【java/Json】用Java对象构建Json语法树
本文后续:https://www.cnblogs.com/xiandedanteng/p/11973129.html 编译第一步:将文本解析成Java对象构成的语法树 第二步:将语法树输出整形好的Js ...
- json 的使用 Java对象转json
1. jsonlib:个人感觉最麻烦的一个需要导入的包也多,代码也相对多一些. 2.Gson:google的 3.FastJson:阿里巴巴的,个人觉得这个比较好,而且据说这个也是性能最好一个. 下面 ...
- jackson java对象和json对象的互相转换
概述 Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的Java Json解析器”. Jackson框架包含了3个核心库:streaming,databind,annotation ...
- Java对象转JSON时如何动态的增删改查属性
1. 前言 日常开发中少不了JSON处理,少不了需要在JSON中添加额外字段或者删除特定字段的需求.今天我们就使用Jackson类库来实现这个功能. 2. JSON字符串增加额外字段 假如我们有这样结 ...
- JSON数据与Java对象的相互转换
JSON数据与Java对象的相互转换 JSON解析器 常见的解析器:Jsonlib .Gson. fastjson. jackson JSON转化为Java对象 使用步骤: 1.导入jackson的相 ...
- java对象与json对象间的相互转换
工程中所需的jar包,因为在网上不太好找,所以我将它放到我的网盘里了,如有需要随便下载. 点击下载 1.简单的解析json字符串 首先将json字符串转换为json对象,然后再解析json对象,过程如 ...
- Java对象、Json、Xml转换工具Jackson使用
在Java项目中將一个对象转换成一段Json格式的字符串是非常常见的,能够实现这种需求的工具包也比较多,例如Gson.JSON-lib.Jackson等等.本文主要介绍Jackson的使用,Jacks ...
- Java开发中json使用,各对象与json相互转换
Json:一种网络通信使用的数据格式,因为便于解析,比较流行,对象可以转为json,同样json也可以转对象. 下面介绍下Json工具的简单使用(fastjson && jackson ...
随机推荐
- 微信小程序开发初探
一.关于微信小程序 1.1 小程序诞生的背景 张小龙说道: (1)一切以用户价值为依归→用户是微信的核心,所以微信中没有很多与客户无关的功能,比如QQ中的乱七八糟一系列东西. (2)让创造发挥价值→所 ...
- [转载]大型网站应用中 MySQL 的架构演变史
没有什么东西是一成不变的,包含我们的理想和生活!MySQL作为一个免费的开源的关系型数据库,深受大家喜爱,从最初的无人问津到当下的去IOE,都体现出了MySQL举足轻重的作用.今天我们就从淘宝的发展来 ...
- [转]Android Binder设计与实现 - 设计篇
摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder ...
- 【原】Masonry+UIScrollView的使用注意事项
[原]Masonry+UIScrollView的使用注意事项 本文转载请注明出处 —— polobymulberry-博客园 1.问题描述 我想实现的使用在一个UIScrollView依次添加三个UI ...
- 浏览器HTTP缓存原理分析
以前项目中遇到了很多浏览器缓存相关的问题,也在网上查过资料,搞过服务器的配置,来确保客户端加载服务器资源的速度和资源有效性.最近仔细看了下http协议中和缓存相关的一些属性,总结一下. 浏览器缓存原理 ...
- web开发调试神器——fiddler的使用
好累 以后再写 http://docs.telerik.com/fiddler/knowledgebase/autoresponder
- 菜鸟浅析JAVA,.NET,C/C++的区别
前言 以前经常看一些文章说到JAVA,.NET的区别,有时候C++er也会过来 凑凑热闹,突然发现这几天手停不下来了,也想写一篇文章 来分析一下 JAVA,.NET,C/C++的优缺点以及他们之间谁“ ...
- 你真的会玩SQL吗?让人晕头转向的三值逻辑
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- IL实现简单的IOC容器
既然了解了IL的接口和动态类之间的知识,何不使用进来项目实验一下呢?而第一反应就是想到了平时经常说的IOC容器,在园子里搜索了一下也有这类型的文章http://www.cnblogs.com/kkll ...
- 安装MySql for Visual Studio的坑
阅读目录 问题描述 解决过程 解决方案 总结 回到顶部 问题描述 安装MySql for Visual Studio 一般来说是为了能在VS的服务器数据连接的数据源中能选择MySql类型,如下图: 但 ...