fastjson怎么判断节点是JSONObject还是JSONArray

因为历史原因和特殊业务逻辑,有个接口会返回如下3种格式的json字符串:

{
    "code": 200,
    "data": "xxxxxxx",
    "msg": "success"
}

{
    "code": 200,
    "data": {
        "info": {
            "title": "xxx",
            "desc": "xxx"
        },
        "ext": {
            "desc": "xxx"
        }
    },
    "msg": "success"

{
    "code": 200,
    "data": [{
        "title": "xxx",
        "desc": "xxx"
    }, {
        "title": "xxx",
        "desc": "xxx"
    }],
    "msg": "success"

data这个节点下,可能是一个纯字符串,可能是一个JSONObject,还有可能是一个JSONArray,我们现在要做的是,写一个方法,解析这个json,组装一个统一的返回值供外部调用,问题点就在于怎么判断data节点下是string还是JSONObject还是JSONArray。 

前提条件,fastjson用的版本是1.2.83

下面说一下判断方法,刚开始百度搜索出来的结果,大部分是下面这种判断方式:

public static void main(String[] args) {
        String objStr = "{\"code\":200,\"data\":{\"info\":{\"title\":\"xxx\",\"desc\":\"xxx\"},\"ext\":{\"desc\":\"xxx\"}},\"msg\":\"success\"}";
        String aryStr = "{\"code\":200,\"data\":[{\"title\":\"xxx\",\"desc\":\"xxx\"},{\"title\":\"xxx\",\"desc\":\"xxx\"}],\"msg\":\"success\"}";
        String spStr = "{\"code\":200,\"data\":\"xxxxxxx\",\"msg\":\"success\"}";

        JSONObject jsonObject = JSON.parseObject(spStr);
        Object object = JSON.parse(jsonObject.getString("data"));
        if (object instanceof JSONObject) {
            System.out.println("JSONObject");
        } else if (object instanceof JSONArray) {
            System.out.println("JSONArray");
        } else {
            System.out.println("string");
        }
    }

 上面这种写法,对于data节点下是JSONObject或JSONArray,是能正常判断的,但是如果data下直接是string纯字符串的话,JSON.parse会报错:

Exception in thread "main" com.alibaba.fastjson.JSONException: illegal state. x
    at com.alibaba.fastjson.parser.JSONLexerBase.scanHex(JSONLexerBase.java:5109)
    at com.alibaba.fastjson.parser.JSONLexerBase.nextToken(JSONLexerBase.java:203)
    at com.alibaba.fastjson.parser.DefaultJSONParser.<init>(DefaultJSONParser.java:170)
    at com.alibaba.fastjson.parser.DefaultJSONParser.<init>(DefaultJSONParser.java:141)
    at com.alibaba.fastjson.JSON.parse(JSON.java:180)
    at com.alibaba.fastjson.JSON.parse(JSON.java:191)
    at com.alibaba.fastjson.JSON.parse(JSON.java:147)

 后来在fastjson的github搜索,发现可以用JSONValidator来做判断,代码如下:

public static void main(String[] args) {
        String objStr = "{\"code\":200,\"data\":{\"info\":{\"title\":\"xxx\",\"desc\":\"xxx\"},\"ext\":{\"desc\":\"xxx\"}},\"msg\":\"success\"}";
        String aryStr = "{\"code\":200,\"data\":[{\"title\":\"xxx\",\"desc\":\"xxx\"},{\"title\":\"xxx\",\"desc\":\"xxx\"}],\"msg\":\"success\"}";
        String spStr = "{\"code\":200,\"data\":\"xxxxxxx\",\"msg\":\"success\"}";

        JSONObject jsonObject = JSON.parseObject(spStr);
        JSONValidator validator = JSONValidator.from(jsonObject.getString("data"));
        JSONValidator.Type jsonType = validator.getType();
        System.out.println(jsonType);
        if (jsonType == JSONValidator.Type.Object) {
            System.out.println("JSONObject");
        } else if (jsonType == JSONValidator.Type.Array) {
            System.out.println("JSONArray");
        } else {
            System.out.println("string");
        }

    }

简单看了一下源码,主要是通过validate()方法来做的判断

public boolean validate() {
    if (validateResult != null) {
        return validateResult;
    }

    for (;;) {
        if (!any()) {
            validateResult = false;
            return false;
        }
        skipWhiteSpace();

        count++;
        if (eof) {
            validateResult = true;
            return true;
        }

        if (supportMultiValue) {
            skipWhiteSpace();
            if (eof) {
                break;
            }
            continue;
        } else {
            validateResult = false;
            return false;
        }
    }

    validateResult = true;
    return true;
}

更加具体详细的代码,请大家移步fastjson的仓库自己看一下

最后结论:

在java中用fastjson,可以通过JSONValidator来判断节点类型

猜你喜欢

转载自blog.csdn.net/wangkaichenjuan/article/details/130193845