Part 0.为啥要拆它?
最近实验室任务量不大,故决定找一些不错的开源项目拆开看看,学习下设计模式和实现工程的细节。看一看一些优秀的工程都是怎么实现的。
前几天刚帮同学拆了一个超轻量级的json框架cJSON,发现拆开源工程的感觉很不错,于是找了下Java的解决方案,比较有代表性的有谷歌的gson和阿里的fastjson。作为国人就先拆国产作品吧~~
首先我们要知道这东西是什么,怎么用,再从入口点开始逐步剥皮。
0.1 Fastjson是什么?
Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。
0.2 Fastjson怎么用?
Fastjson的最主要的使用入口是com.alibaba.fastjson.JSON,接口如下:
import com.alibaba.fastjson.JSON;
public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray
public static final JSONObject parseObject(String text); // 把JSON文本parse成JSONObject
public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBean
public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray
public static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合
public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本
public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本
public static final Object toJSON(Object javaObject); 将JavaBean转换为JSONObject或者JSONArray。
下面分别演示一下:
首先我们用作示例的json串是这样的:
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": [ "GML", "XML" ] },
"GlossSee": "markup" }
}
}
}
}
首先运行这段代码:
public static void main( String[] args )
{
String text="{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\",\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\",\"GlossDef\":{\"para\":\"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},\"GlossSee\":\"markup\"}}}}}";
Object json = JSON.parse(text);
System.out.println(json);
}
可以看到输出了一个JSONObject,parseObject(text)
和parseArray(text)
也类似。
public static void main( String[] args )
{
String text="{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\",\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\",\"GlossDef\":{\"para\":\"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},\"GlossSee\":\"markup\"}}}}}";
JsonBean bean = JSON.parseObject(text, JsonBean.class);
System.out.println(bean);
}
在这里我们建了一个JavaBean,用来对应Json串的各个字段,运行这段代码后,发现JSON串的值已经准确的装入javabean中。
控制台输出如下:
JsonBean [glossary=Glossary [title=example glossary, glossdiv=Glossdiv [title=S, glosslist=Glosslist [glossentry=Glossentry [id=SGML, sortas=SGML, glossterm=Standard Generalized Markup Language, acronym=SGML, abbrev=ISO 8879:1986, glossdef=Glossdef [para=A meta-markup language, used to create markup languages such as DocBook., glossseealso=[GML, XML]], glosssee=markup]]]]]
以上是反序列化部分,就是对json串的解析。
接下来看看序列化部分是什么样的。
按上面的程序,我们已经得到了javabean,下面把他还原成json。
public static void main( String[] args )
{
String text="{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\",\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\",\"GlossDef\":{\"para\":\"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},\"GlossSee\":\"markup\"}}}}}";
JsonBean bean = JSON.parseObject(text, JsonBean.class);
String text2 = JSON.toJSONString(bean);
System.out.println(text2);
}
执行一下,控制台输出了原来那个json,和text串是等价的。
等等,原来的接口里面还有个重载函数,可以加布尔值,那么我们加个true试试:String text2 = JSON.toJSONString(bean,true);
恩,这下控制台输出的就不是一行了,而是看起来更易读的形式:
{
"glossary":{
"glossdiv":{
"glosslist":{
"glossentry":{
"abbrev":"ISO 8879:1986",
"acronym":"SGML",
"glossdef":{ "glossseealso":[ "GML", "XML" ], "para":"A meta-markup language, used to create markup languages such as DocBook." },
"glosssee":"markup",
"glossterm":"Standard Generalized Markup Language",
"id":"SGML",
"sortas":"SGML" }
},
"title":"S"
},
"title":"example glossary"
}
}
没错,这个参数叫prettyFormat,打印出来的确实pretty多了~~