说说org.json.JSONObject功能和源码(终)

Java 发表评论

      前两弹说了JSONObject存储结构是一个HashMap,都是一些字符串的解析操作,代码容易理解。输出视觉友好的JSON文本,可以这样写:

public class JSONObjectTest {
    public static void main(String[] a){
        String json = "{china:{hubei:[wuhan,yichang],hunan: changsha},status:1}";
        JSONObject jsonObject = new JSONObject(json);
        System.out.println(jsonObject.toString(4));
    }
}

输出为:

{
    "china": {
        "hubei": [
            "wuhan",
            "yichang"
        ],
        "hunan": "changsha"
    },
    "status": 1
}

结果中带了换行和缩进,下面看toString(…)方法:

@Override
public String toString() {
    try {
        return this.toString(0);
    } catch (Exception e) {
        return null;
    }
}
//重载方法,indentFactor是视觉上相对上一级缩进空格数
public String toString(int indentFactor) throws JSONException {
    StringWriter w = new StringWriter();
    //获取最终存文本信息的StringBuffer对象
    synchronized (w.getBuffer()) {
        return this.write(w, indentFactor, 0).toString();
    }
}

      JSONObject对象转字符串就是在写一个StringBuffer对象,将对象中的基本类型等信息合适的打印出。下面看public Writer write(Writer writer, int indentFactor, int indent):

//最后内容都在writer对象里,indentFactor是相对上一级缩进空格数,toString(...)方法调用时传的indent为0
public Writer write(Writer writer, int indentFactor, int indent)
        throws JSONException {
    try {
        //commanate == true标记取完一个value,用于加上','和换行
        boolean commanate = false;
        final int length = this.length();
        writer.write('{');

        //只有一个key时不换行
        if (length == 1) {
            final Entry<String,?> entry = this.entrySet().iterator().next();
            final String key = entry.getKey();
            //输出的key都带有引号,字符串value也带
            //quote(key)这个方法给字符串加引号,让转义字符、等合理的打印出
            writer.write(quote(key));
            writer.write(':');
            if (indentFactor > 0) {
                writer.write(' ');
            }
            try{
                writeValue(writer, entry.getValue(), indentFactor, indent);
            } catch (Exception e) {
                throw new JSONException("Unable to write JSONObject value for key: " + key, e);
            }
        } else if (length != 0) {   //缩进时
            //indent是上一级的缩进量,JSONObject等中比上一级多缩进一个indentFactor
            final int newindent = indent + indentFactor;
            for (final Entry<String,?> entry : this.entrySet()) {
                if (commanate) {
                    writer.write(',');
                }
                if (indentFactor > 0) {
                    writer.write('\n');  //换行
                }
                indent(writer, newindent);  //填充newindent数量空格
                final String key = entry.getKey();
                writer.write(quote(key));
                writer.write(':');
                if (indentFactor > 0) {
                    writer.write(' ');
                }
                try {
                    //写value,value可以是基本类型、JSONObject、JSONArray等
                    writeValue(writer, entry.getValue(), indentFactor, newindent);
                } catch (Exception e) {
                    throw new JSONException("Unable to write JSONObject value for key: " + key, e);
                }
                commanate = true;  //换行
            }
            if (indentFactor > 0) {
                writer.write('\n');
            }
            indent(writer, indent);  //最后的'}'缩进
        }
        writer.write('}');
        return writer;
    } catch (IOException exception) {
        throw new JSONException(exception);
    }
}

     上面只放了设计的关键代码,toString(…)主要点就是在操作一个StringBuffer对象,在何时填充换行和缩进。其他的代码看看就知道,就不一一介绍。JSONObject主要代码就写完了,代码总体设计上比较清晰简洁,足以满足开发中需要的JSON对象的处理。

发表评论

邮箱地址不会被公开。 必填项已用*标注

昵称 *