使用gson封装操作json的工具类

本文介绍如何利用Gson库创建一个方便的工具类,用于在Java中进行JSON对象的序列化和反序列化操作。通过实例代码演示了如何封装基本的JSON解析和生成方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package utils;

import com.google.gson.*;

import java.lang.reflect.Array;
import java.util.Map;

/**
 * 使用 gson 封装的操作 json 的工具类
 */
public final class EasyJson {

    /**
     * 全局的 Gson 转换对象
     */
    private static final Gson gson = new Gson();

    /**
     * 通过父级对象实现树形结构
     */
    private EasyJson parent;

    /**
     * 保存数据的对象
     * 树形结构的节点,可以作为分支节点或者叶节点
     */
    private JsonElement data;

    private EasyJson(EasyJson parent, boolean isObj) {
        this(parent, isObj ? new JsonObject() : new JsonArray());
    }

    private EasyJson(EasyJson parent, JsonElement data) {
        this.data = data;
        this.parent = parent;
    }

    /**
     * 获取EasyJson实例
     *
     * @return 默认的 JsonObject
     */
    public static EasyJson getInstance() {
        return getInstance(null, Boolean.TRUE);
    }

    /**
     * 获取EasyJson实例
     *
     * @param isObj 如果为true,构造实例为JsonObject,反之为JsonArray
     */
    public static EasyJson getInstance(boolean isObj) {
        return getInstance(null, isObj);
    }

    /**
     * 获取EasyJson实例
     *
     * @param parent 上层实例
     * @param isObj  是否构造为JsonObject
     */
    public static EasyJson getInstance(EasyJson parent, boolean isObj) {
        return new EasyJson(parent, isObj);
    }

    /**
     * 获取EasyJson实例
     *
     * @param data 指定构造的Json数据
     */
    public static EasyJson getInstance(JsonElement data) {
        return getInstance(null, data);
    }

    /**
     * 获取EasyJson实例
     *
     * @param parent 上层实例
     * @param data   指定构造的Json数据
     */
    public static EasyJson getInstance(EasyJson parent, JsonElement data) {
        return new EasyJson(parent, data);
    }

    /**
     * 创建下一层EasyJson对象,并将新建的对象返回
     *
     * @param name 新建的EasyJson对象在上级对象中的名称
     * @return 返回新建节点的指针
     */
    public EasyJson subObj(String name) {
        EasyJson sub = getInstance(this, Boolean.TRUE);
        this.put(name, sub.data);
        return sub;
    }

    /**
     * 基于当前 JsonArray 对象,创建下一层EasyJson对象
     *
     * @return 返回新建节点的指针
     */
    public EasyJson subObj() {
        EasyJson sub = getInstance(this, Boolean.TRUE);
        this.add(sub.data);
        return sub;
    }

    /**
     * 构建新的 JsonArray 节点,并返回节点指针
     *
     * @param name 新建的EasyJson对象在上级对象中的名称
     * @return 返回新建节点的指针
     */
    public EasyJson subArr(String name) {
        EasyJson sub = getInstance(this, Boolean.FALSE);
        this.put(name, sub.data);
        return sub;
    }

    /**
     * 构建新的 JsonArray 节点,并返回节点指针
     *
     * @return 返回新建节点的指针
     */
    public EasyJson subArr() {
        EasyJson sub = getInstance(this, Boolean.FALSE);
        this.add(sub.data);
        return sub;
    }

    /**
     * 结束子 EasyJson 对象的操作,返回上层对象
     *
     * @return 返回上层对象的指针
     */
    public EasyJson endSub() {
        return this.parent;
    }

    /**
     * 构造上层对象,对象实例为 JsonObject
     *
     * @param name 当前对象在上层对象中的名称
     * @return 返回上层对象的指针
     */
    public EasyJson supObj(String name) {
        EasyJson parent = getInstance(this, Boolean.TRUE);
        parent.put(name, this.data);
        this.parent = parent;
        return parent;
    }

    /**
     * 构造上层对象,对象实例为 JsonArray
     *
     * @return 返回上层对象的指针
     */
    public EasyJson supArr() {
        EasyJson parent = getInstance(this, Boolean.FALSE);
        parent.add(this.data);
        this.parent = parent;
        return parent;
    }

    /**
     * 给 JsonObject 对象添加键值对
     * 请注意,如果属性中已有相同的键,那么旧值将会被覆盖为新值。
     * 示例:put("add", "a").put("add", "b"); // json:{"add":"b"}
     *
     * @param name 键
     * @param val  值
     * @return 返回当前 EasyJson 对象
     */
    public EasyJson put(String name, Object val) {
        if (data instanceof JsonObject) {
            ((JsonObject) data).add(name, adapter(val));
        } else {
            throw new IllegalArgumentException("Must put for JsonObject.");
        }
        return this;
    }

    /**
     * 给 JsonArray 对象添加值
     *
     * @param val 值
     * @return 返回当前 EasyJson 对象
     */
    public EasyJson add(Object val) {
        if (data instanceof JsonArray) {
            ((JsonArray) data).add(adapter(val));
        } else {
            throw new IllegalArgumentException("Must put for JsonArray.");
        }
        return this;
    }

    /**
     * 给 JsonArray 对象添加值
     *
     * @param val 类型必须是JsonArray,Array,Iterable
     * @return 返回当前 EasyJson 对象
     */
    public EasyJson addAll(Object val) {
        if (data instanceof JsonArray) {
            JsonArray jsonArray = adapter(val).getAsJsonArray();
            ((JsonArray) data).addAll(jsonArray);
        } else {
            throw new IllegalArgumentException("Must put for JsonArray.");
        }
        return this;
    }

    /**
     * 将 Object 类型的数据构造为适配的 JsonElement 对象
     * 当前支持的类型有:基本类型,string,Iterable,Map,JsonElement,EasyJson
     *
     * @param obj 数据
     * @return 返回适配的 JsonElement 对象
     * @throws IllegalArgumentException 如果参数是不支持类型,将会抛出该异常
     */
    private static JsonElement adapter(Object obj) {
        if (obj == null) {
            return JsonNull.INSTANCE;
        }
        Class clazz = obj.getClass();
        if (obj instanceof JsonElement) {
            return (JsonElement) obj;
        } else if (obj instanceof EasyJson) {
            return ((EasyJson) obj).data;
        } else if (obj instanceof String) {
            return new JsonPrimitive((String) obj);
        } else if (obj instanceof Number) {
            return new JsonPrimitive((Number) obj);
        } else if (obj instanceof Character) {
            return new JsonPrimitive((Character) obj);
        } else if (obj instanceof Boolean) {
            return new JsonPrimitive((Boolean) obj);
        } else if (obj instanceof Iterable) {
            Iterable iterable = (Iterable) obj;
            return adapterJsonArray(iterable);
        } else if (clazz.isArray()) {
            return adapterJsonArray(obj);
        } else if (obj instanceof Map) {
            Map map = (Map) obj;
            return adapterJsonObject(map);
        } else {
            throw new IllegalArgumentException("Cannot adapter this classType:" + clazz.getName());
        }
    }

    /**
     * 将集合类型的数据适配为 JsonArray 对象
     *
     * @param iterable 数据
     * @return 返回适配的 JsonArray 对象
     */
    private static JsonArray adapterJsonArray(Iterable iterable) {
        JsonArray arr = new JsonArray();
        for (Object o : iterable) {
            arr.add(adapter(o));
        }
        return arr;
    }

    /**
     * 将数组类型的数据适配为 JsonArray 对象
     *
     * @param arr 数据
     * @return 返回适配的 JsonArray 对象
     * @throws IllegalArgumentException 如果参数不是数组类型,将会抛出该异常
     */
    private static JsonArray adapterJsonArray(Object arr) {
        JsonArray jsonArr = new JsonArray();
        int length = Array.getLength(arr);
        for (int i = 0; i < length; i++) {
            JsonElement ele = adapter(Array.get(arr, i));
            jsonArr.add(ele);
        }
        return jsonArr;
    }

    /**
     * 将 Map 类型的数据适配为 JsonObject 对象
     *
     * @param map 数据
     * @return 返回适配的 JsonObject 对象
     * @throws IllegalArgumentException 如果 map 中含有值为 null 的键,将会抛出该异常
     */
    private static JsonObject adapterJsonObject(Map map) {
        JsonObject jsonObj = new JsonObject();
        for (Object o : map.keySet()) {
            if (o == null) {
                throw new IllegalArgumentException("Map key cannot is null.");
            }
            String key = o.toString();
            JsonElement val = adapter(map.get(key));
            jsonObj.add(key, val);
        }
        return jsonObj;
    }

    @Override
    public String toString() {
        return gson.toJson(data);
    }

    public JsonElement getData() {
        return this.data;
    }

    public static JsonObject getJsonObject(JsonElement data, String path) {
        return (JsonObject) getPath(data, path);
    }

    public static JsonArray getJsonArray(JsonElement data, String path) {
        return (JsonArray) getPath(data, path);
    }

    public static String getAsString(JsonElement data, String path) {
        return getJsonPrimitive(data, path).getAsString();
    }

    public static char getAsChar(JsonElement data, String path) {
        return getJsonPrimitive(data, path).getAsCharacter();
    }

    public static boolean getAsBoolean(JsonElement data, String path) {
        return getJsonPrimitive(data, path).getAsBoolean();
    }

    public static long getAsLong(JsonElement data, String path) {
        return getJsonPrimitive(data, path).getAsLong();
    }

    public static int getAsInt(JsonElement data, String path) {
        return getJsonPrimitive(data, path).getAsInt();
    }

    public static double getAsDouble(JsonElement data, String path) {
        return getJsonPrimitive(data, path).getAsDouble();
    }

    private static JsonPrimitive getJsonPrimitive(JsonElement data, String path) {
        return (JsonPrimitive) getPath(data, path);
    }

    /**
     * 根据路径获取 json 中对应的值。考虑到方便外部 JsonElement 对象的使用,设为静态方法
     * 伪代码示例:
     *      JsonElement json = {"name": "frank", "language": ["Java", "GoLang"], "pet": {"clazz":"dog", "name":"BenBen"}}
     *      getPath(json, "language:1"); // JsonPrimitive("GoLang")
     *      getPath(json, "pet/name"); // JsonPrimitive("BenBen")
     *
     * @param data 为了调用方便,所以使用了JsonElement作为参数类型
     * @param path name 以 / 分隔,如果是取JsonArray的值,在 name 后加上冒号和下标
     * @return 返回 Json 中对应的值,如果节点中没有找到对应的值,将会返回null
     * @throws ClassCastException 如果传入的 data 类型不是分支节点将会抛出类型转换异常
     */
    private static JsonElement getPath(JsonElement data, String path) {
        JsonElement ret = null;
        if (data != null) {
            JsonElement ele = data;
            String[] split = path.split("/");
            for (String component : split) {
                if (ele == null) {
                    break;
                }
                if (component.contains(":")) {
                    String[] split2 = component.split(":");
                    ele = ((JsonObject) ele).get(split2[0]);
                    int index = Integer.parseInt(split2[1]);
                    ele = ((JsonArray) ele).get(index);
                } else {
                    ele = ((JsonObject) ele).get(component);
                }
            }
            ret = ele;
        }
        return ret;
    }
}

测试代码:

@Test
    public void testEasyJson() {
        EasyJson easyJson = getInstance().put("name", "frank")
                .subArr("language").add("Java").add("GoLang").endSub()
                .subObj("pet").put("clazz", "dog").put("name", "BenBen").endSub();
        System.out.println(getPath(easyJson.getData(), "language:1"));
        System.out.println(getPath(easyJson.getData(), "pet/name"));
    }

感谢参考博文:https://blog.youkuaiyun.com/axuanqq/article/details/51441590

end~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值