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来判断节点类型

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以参考以下代码实现: ```java import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; public class JSONUtils { public static void convertNestedJSONObject(JSONObject jsonObject) { for (String key : jsonObject.keySet()) { Object value = jsonObject.get(key); if (value instanceof JSONObject) { JSONArray nestedArray = new JSONArray(); nestedArray.add(value); jsonObject.put(key, nestedArray); convertNestedJSONObject((JSONObject) value); } else if (value instanceof JSONArray) { convertNestedJSONObject((JSONArray) value); } } } public static void convertNestedJSONObject(JSONArray jsonArray) { for (int i = 0; i < jsonArray.size(); i++) { Object item = jsonArray.get(i); if (item instanceof JSONObject) { JSONArray nestedArray = new JSONArray(); nestedArray.add(item); jsonArray.set(i, nestedArray); convertNestedJSONObject((JSONObject) item); } else if (item instanceof JSONArray) { convertNestedJSONObject((JSONArray) item); } } } } ``` 这个工具类包含了两个方法,分别用于处理 `com.alibaba.fastjson.JSONObject` 和 `com.alibaba.fastjson.JSONArray` 对象。对于 `JSONObject`,我们遍历其中的每个键值对,如果值是 `JSONObject` 对象,就将其包装成一个嵌套的 `JSONArray` 对象,并递归地调用自身处理嵌套的情况。对于 `JSONArray`,我们遍历其中的每个元素,如果元素是 `JSONObject` 对象,就将其包装成一个嵌套的 `JSONArray` 对象,并递归地调用自身处理嵌套的情况。需要注意的是,在处理 `JSONObject` 的时候,需要使用 `put` 方法替换原有键值对,而在处理 `JSONArray` 的时候,需要使用 `set` 方法替换原有元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值