Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

slive/simpleJson

Repository files navigation

Java实现一个简单的Json解析器

基于Json进行数据传输在现在的互联网应用中已经非常非常广泛,所以了解Json数据结构是很有必要的。为了加深理解,自己动手实现一个简单的Json解析器。 实现Json解析器包括两方面: a、将Java 对象转换为Json String b、将Json String解析为Java对象

简单了解Json数据结构

Json主要由如下两种结构和值组成: Json Object,即为键值对方式,键只能为字符串类型,值则如常规字符串,数字,日期,对象,hash表,数组,集合等等。由"{"开头,"}"结尾,内由多组键-值组成,键-值中间用":"隔开,键值与键值之前用","隔开,具体如下:

<img src="http://www.json.org/object.gif"</img

Json Array,由"["开头,"]"结尾,内由多个值组成,每个值之间用","隔开,具体如下:

<img src="http://www.json.org/array.gif"</img

Json Value,可以是字符串,数字,布尔,或者嵌套Json Object,Array,也可能为空,具体如下:

<img src="http://www.json.org/value.gif"</img

Java对象类型分类

对于Java对象的类型,本文及其后面文章约定了几种类型的定义(可能定义有一定的局限性和不完整):

1、简单类型
a)Java的8种基本类型及其包装类型
b)Java String类型
c)继承Java Number类的类型
2、Collection类型
a)实现Java Collection接口的类型
b)继承Java Collection 接口的类型
3、Map类型
a)实现Java Map接口类型
b)继承Java Map接口的类型
4、数组类型
即Java 中定义的数组类型
5、复合类型
以上类型除外

代码见TypeUtils.java:


 /*
 * 即 boolean、byte、char、short、int、long、float 和 double
 * @see Class.isPrimitive()
 */
 public static boolean isPrimitiveType(ClassJava 对象转Json String大体流程如下:

1、对于输入的Java对象实例,首先判断是属于那种类型,然后根据不同类型分别进行处理,处理简单类型,其它都是需要进行嵌套处理,对于Map,集合,数组类型,还需要循环嵌套处理,最终底层来看都是根据简单类型进行处理,然后将处理结果统一到一个StringBuilder中返回。
2、简单类型处理,对应Json Value,直接将简单类型转换为String类型,然后返回。
3、复合类型处理,对应Json Object,这里只能处理pojo类,其它不符合该要求的,将无法解析。通过判断对象实例的getter,setter获取对应的字段名称,也即为key,然后通过getter方法获取值,再对值回到1中嵌套解析处理。
4、Map类型处理,也是对应Json Object,这里的Map中的key对应着Json key,通过循环迭代获取值,再对值回到1中嵌套解析处理。
5、数组/集合类型处理,也是对应Json Array,通过循环迭代获取值,再对值回到1中嵌套解析处理。
最后再将结果返回即可。
代码参考Json.java:

/* 将类转换为json格式字符串
 */
 public static String toJsonString(Object jsonObj) {
 if (jsonObj == null) {
 return null;
 }
 ClassJsonObject实际就是对应Json结构,val-Json Value(val只能是Java String,Java Map,Java Lis,其中Map-Json Object,List-Json Array),key- Json key三种结构,由于是嵌套的,所以还定义了一个parent,具体见Json#JsonObject.java:
将Json String解析为JsonObject流程图:
最终解析出来的是一个JsonObject对象实例,该对象实例中又包含了子JsonObject,就像一个树结构,具体代码如下:

private static JsonObject toJsonObject(String jsonStr) {
 if (CommonUtils.isEmpty(jsonStr)) {
 return null;
 }
 JsonObject jb = null;
 StringBuilder sbd = new StringBuilder();
 char[] jcs = jsonStr.toCharArray();
 int jLen = jcs.length;
 String key = null;
 String val = null;
 Object jVal = null;
 char jc;
 for (int index = 0; index < jLen; index++) {
 jc = jcs[index];
 if (jc == '{') {
 // 初始化为Map
 jb = new JsonObject(jb, key, new HashMap

将Java JsonObject类解析为Java对象实例

这里会有两个参数,一个是Java JsonObject实例值,一个是目标Java对象class,转换后的结果是目标Java对象实例。如《Java实现一个简单的Json解析器(一)》提到的本文的Java对象类型分类,分别对目标Java对象的类型进行判断,根据不同类型,分别做不同的类型解析处理,解析流程如下: <img src="JavaParse.png"</img

有几个地方需要重点说明一下: 1、整个解析过程是嵌套执行,目标Java对象的类型和JsonObject对象的类型能对应上才能解析,否则可能被丢弃,对应关系大体如下: (1)目标Java对象为简单类型,则JsonObject对象的值可以为任意类型,但解析是强制转换为String再进行解析。 (2)目标Java对象为复合或者Map类型,则JsonObject对象的值只能为Map类型。 (3)目标Java对象为集合或者数组类型,则JsonObject对象的值只能为集合类型。 2、对于目标Java对象为非简单类型时,需要判断出pojo类中的字段,或者Map,数组,集合中定义的值对应哪个Java类(比如byte[String],则定义的值为String.class类,又比如Map<String,TestDto,则定义的值为TestDto.class类,若无法确定,则取默认的Java的Object.class),以便作为新的目标Java对象进行嵌套解析,最终最底层都是调用简单类型进行处理,具体代码见如下:

3、对于目标Java对象中有些字段使用接口进行定义,若无法找到具体的实现类时,则通过Java代理实现setter和getter方法,代码实现如下:

static class JsonInvocationHandler implements InvocationHandler {
 private Map srcVals = null;
 
 private Map
1、日期(格式)处理
2、数值的处理,如科学计数法转换等
3、字符串编码处理,避免出现解析或者转换的乱码
4、格式化输出处理
5、性能和容错处理

总结

1、理解Json数据结构基础上,通过与Java语言特性进行对应,实现Json解析器功能
2、划分类型,针对不同类型进行不同的处理,类型最终处理都归结为简单类型的处理
3、针对复合类型处理,需化繁为简进行处理
4、针对集合或者Map类型处理,首先要能够提取集合中对象的类型或者值,然后进行循环处理
5、理解代理实现类

参考

Json介绍:http://www.json.org/ 阿里巴巴Fastjson:https://fastjson.codeplex.com/

About

Java实现一个简单的Json解析器

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

AltStyle によって変換されたページ (->オリジナル) /