解析Json文本——如何将Json文本转化为Java对象
????? Json是一种简单小巧的数据交换格式,在Web开发中获得了广泛应用。网络上有很多Json库,光用Java编写的就不下二十个之多。无论哪一个Json库都必须具有一个基本功能,就是把Json文本转换为用本语言表示的数据结构,本文就是介绍如何把Json文本一字符一字符的解析成Java对象。
????? 如果要问解析Json需要哪些基础知识的话,计算机科班出身的读者立马就能想到大学时学过的编译原理这门课程。解析Json就是需要利用编译原理的知识,不过Json非常简单,解析它不必使用所有的编译技术,只要了解词法分析就可以了。不了解词法分析也不要紧,Json非常简单,不用词法分析也能解析。本文根据bantouyan-json库中解析Json文本的方法编写,不需要词法分析的基础。
?
????? 在介绍怎样解析Json文本之前,我们先回顾一下Json的定义。如果要了解Json的详细定义可以查看RFC4627文档,或者www.json.org网站。本文只作简要的介绍。
?
?
?
????? 上面的五幅图像分别定义了Json的对象、数组、Value、字符串与数字。Json文本由一个Json对象或Json数组构成,无论是Json对象或者Json数组,还是Json字符串或数字,都是一个Json Value。
????? Json文本由构成Json的必要字符和额外的空白字符构成,解析它就要忽略额外的空白字符并将剩余部分转换为Java对象。本文按照bantouyan-json库提供的方法解析Json文本,介绍时做了一些适当的简化。
?
????? bantouyan-json库的解析功能由内部类JsonTextParser提供,JsonTextParser类的定义如下:
private JsonPrimitive parseJsonConstant(String constName, int[] constAry, int endChar)throws IOException, JsonException{ JsonPrimitive json = null; for(int i=0; i<constAry.length; i++) { if(ch != constAry[i]) { // throw exception } next(); } if(ch != ',' && ch != endChar && !isBlankCharacter(ch)) { // throw exception } json = (constAry == trueAry)? Json.trueJson: (constAry == falseAry)? Json.falseJson: Json.nullJson; return json;}
参数endChar表示Json常量后除','外允许跟的另外一个分界符,参数constAry用于比较所扫描的字符,参数constName用来报告更直观的异常。
?
????? 本文介绍的算法对字符串只进行一次扫描,不需要回溯,因此时间复杂度为O(n)。一遍扫描的好处是不用回溯,算法简单,坏处是如果被解析的字符串格式不正确,那么只能报告所发现的第一个错误。好在大多数情况下本解析的Json文本都是正确的,而且代码一般也不负责修复Json文本的错误,所以采用一次扫描的策略是可行的。
?
?
?
相关阅读:
解析Json——bantouyan-json库概述
解析Json——Json类的静态方法
解析Json——Json类的实例方法
解析Json——操纵JsonObject
解析Json——操纵JsonArray