一个调用多层次json的简便工具类

本文介绍了一个基于fastJson的Java工具类,能便捷地从复杂的JSON格式API返回值中提取所需数据,支持通过路径字符串获取嵌套的值,适用于各种层级的数据结构。

最近一直在调用一些JSON格式的API, 而且返回值没有固定的格式可言,一层一层的取值很麻烦,因此写了一个简便的Java工具类,希望能帮到某些朋友。工具类基于fastJson, 如果想要用于map, JsonObject实现了Java的Map<String, Object>接口, JsonArray实现了List<Object>接口,可以自己稍加调整得到一个通用的类。

package com.jay.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 
 * @author Jay Zhang
 *
 */
public class JsonUtils {

    private static Logger LOGGER = LoggerFactory.getLogger(JsonUtils.class);

    public static boolean has(JSONObject json, String fullPath) {
        try {
            String[] paths = fullPath.split("\\s*\\.\\s*");
            int len = paths.length;
            String path;
            String key;
            Object current = json;
            for (int i = 0; i < len; i++) {
                path = paths[i];
                if (path.isEmpty()) {
                    continue;
                }
                if (path.endsWith("]")) {
                    int index = path.indexOf("[");
                    key = path.substring(0, index);
                    current = ((JSONObject) current).get(key);
                    path = path.substring(index + 1);
                    String[] indice = path.replace("[", "").split("\\]");
                    for (String indx : indice) {
                        if (indx.isEmpty()) {
                            continue;
                        }
                        int i_indx = Integer.valueOf(indx);
                        if (i_indx >= ((JSONArray) current).size()) {
                            return false;
                        }
                        if (i_indx < 0 && ((JSONArray) current).size() + i_indx < 0) {
                            return false;
                        }
                        if (i_indx < 0) {
                            i_indx = ((JSONArray) current).size() + i_indx;
                        }
                        current = ((JSONArray) current).get(i_indx);
                    }
                } else {
                    key = path;
                    if (!((JSONObject) current).containsKey(key)) {
                        return false;
                    }
                    current = ((JSONObject) current).get(key);
                }
            }
            return true;
        } catch (Exception e) {
            LOGGER.error("Error raised when extract the object " + json + ", the path is " + fullPath, e);
            return false;
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T get(JSONObject json, String fullPath) {
        try {
            String[] paths = fullPath.split("\\s*\\.\\s*");
            int len = paths.length;
            String path;
            String key;
            Object current = json;
            for (int i = 0; i < len; i++) {
                path = paths[i];
                if (path.isEmpty()) {
                    continue;
                }
                if (path.endsWith("]")) {
                    int index = path.indexOf("[");
                    key = path.substring(0, index);
                    current = ((JSONObject) current).get(key);
                    path = path.substring(index + 1);
                    String[] indice = path.replace("[", "").split("\\]");
                    for (String indx : indice) {
                        if (indx.isEmpty()) {
                            continue;
                        }
                        int i_indx = Integer.valueOf(indx);
                        if (i_indx < 0) {
                            i_indx = ((JSONArray) current).size() + i_indx;
                        }
                        current = ((JSONArray) current).get(i_indx);
                    }
                } else {
                    key = path;
                    current = ((JSONObject) current).get(key);
                }
            }
            return (T) current;
        } catch (Exception e) {
            LOGGER.error("Error raised when extract the object " + json + ", the path is " + fullPath, e);
            return null;
        }
    }

    public static void main(String[] args) {
        String content = "{\"user\":{\"name\":\"jay\",\"age\":30,\"favorite\":[\"篮球\",\"编程\",[{\"name\":\"吃饭\"},{\"name\":\"睡觉\"}]]}}";
        JSONObject json = JSON.parseObject(content);
        System.out.println("content is " + json.toJSONString());
        System.out.println("user.name is " + JsonUtils.get(json, "user.name"));
        System.out.println("user.age is " + JsonUtils.get(json, "user.age"));
        System.out.println("user.favorite is " + JsonUtils.get(json, "user.favorite"));
        System.out.println("user.favorite[0] is " + JsonUtils.get(json, "user.favorite[0]"));
        System.out.println("user.favorite[2][1] is " + JsonUtils.get(json, "user.favorite[2][1]"));
        System.out.println("user.favorite[2][1].name is " + JsonUtils.get(json, "user.favorite[2][1].name"));
        System.out.println("user.favorite[-1][1].name is " + JsonUtils.get(json, "user.favorite[-1][1].name"));
        System.out.println("user.favorite[-1][-1].name is " + JsonUtils.get(json, "user.favorite[-1][-1].name"));
        System.out.println("user.favorite[-1][-2].name is " + JsonUtils.get(json, "user.favorite[-1][-2].name"));
        System.out.println(
                "Is content contains user.favorite[-1][-2].name? " + JsonUtils.has(json, "user.favorite[-1][-2].name"));
    }
}

运行得到结果如下

content is {"user":{"age":30,"name":"jay","favorite":["篮球","编程",[{"name":"吃饭"},{"name":"睡觉"}]]}}
user.name is jay
user.age is 30
user.favorite is ["篮球","编程",[{"name":"吃饭"},{"name":"睡觉"}]]
user.favorite[0] is 篮球
user.favorite[2][1] is {"name":"睡觉"}
user.favorite[2][1].name is 睡觉
user.favorite[-1][1].name is 睡觉
user.favorite[-1][-1].name is 睡觉
user.favorite[-1][-2].name is 吃饭
Is content contains user.favorite[-1][-2].name? true
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值