Simple Jsonpath Support

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 我们在日常开发中,json几乎随处可见,但是繁琐的json,也给我们解析带来了很多烦恼的问题,多层级的解析,以及各种嵌套对象的解析,那有没有一种更简单的解析方式呢?

前言

iShot2022-12-03 16.33.45.png
我们在日常开发中,json几乎随处可见,但是繁琐的json,也给我们解析带来了很多烦恼的问题,多层级的解析,以及各种嵌套对象的解析,那有没有一种更简单的解析方式呢?

JsonPath

JsonPath与Json的关系,就跟XPath与XML的关系一样,JsonPath是设计来作为JSON 的路径语言,用于确定Json文档中某部分位置的语言,JsonPath的原理就是将Json数据转换为DOM树状结构,并提供在数据结构树种寻找节点以及各个节点的能力。详细的就不赘述,大家可以去官网翻阅查看并使用;https://github.com/json-path/JsonPath

表达式 结果
$.store.book[*].author 获取json中store下book下的所有author值
$..author 获取所有json中所有author的值
$.store.* 所有的东西,书籍和自行车
$.store..price 获取json中store下所有price的值
$..book[2] 获取json中book数组的第3个值
$..book[-2] 倒数的第二本书
$..book[0,1] 前两本书
$..book[:2] 从索引0(包括)到索引2(排除)的所有图书
$..book[1:2] 从索引1(包括)到索引2(排除)的所有图书
$..book[-2:] 获取json中book数组的最后两个值
$..book[2:] 获取json中book数组的第3个到最后一个的区间值
$..book[?(@.isbn)] 获取json中book数组中包含isbn的所有值
$.store.book[?(@.price < 10)] 获取json中book数组中price<10的所有值
$..book[?(@.price <= $['expensive'])] 获取json中book数组中price<=expensive的所有值
$..book[?(@.author =~ /.*REES/i)] 获取json中book数组中的作者以REES结尾的所有值(REES不区分大小写)
$..* 逐层列出json中的所有值,层级由外到内
$..book.length() 获取json中book数组的长度
但是有的时候,我们并不需求这么复杂的解决过程,可能基本就是获取根节点中某个字段或者初始化一个json等等,我们可以在JsonPath的基础上封装一个简单的工具类,来提供便利性

AbstractExtJsonParse

import cn.gov.zcy.service.exp.ExtJsonParseException;
import com.google.common.base.Stopwatch;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * AbstractExtJsonParse
 *
 * @author Duansg
 * @version 1.0
 * @date 2021/11/17 下午8:41
 */
@Slf4j
public abstract class AbstractExtJsonParse {

    /**
     * 根路径
     */
    protected static final String ROOT_PREFIX = "$";

    /**
     * 层级符号
     */
    protected static final String SYMBOL_PREFIX = ".";

    /**
     * 空json
     */
    protected static final String ROOT_EMPTY = "{}";

    /**
     * 获取解析耗时统计的时间单位
     * 
     * @return
     */
    protected abstract TimeUnit getTimeUnit();

    /**
     * 获取耗时日志开关
     * 
     * @return
     */
    protected abstract boolean getShowLog();

    /**
     * 设置扩展字段
     * 
     * @param json
     *            原json
     * @param path
     *            设置路径
     * @param key
     *            需要设置的key
     * @param value
     *            需要设置的值
     * @return
     * @throws ExtJsonParseException
     */
    protected String basePut(String json, String path, Map<String, Object> values) throws ExtJsonParseException {
        final boolean showLog = getShowLog();
        final Stopwatch stopwatch = showLog ? Stopwatch.createStarted() : null;
        try {
            DocumentContext context = JsonPath.parse(json);
            values.forEach((key, value) -> context.put(path, key, value));
            return context.jsonString();
        } catch (Exception e) {
            throw new ExtJsonParseException(e.getMessage());
        } finally {
            if (showLog) {
                log.info("设置完毕,json:{},path:{},values:{},耗时:{} ms", json, path, values,
                    stopwatch.elapsed(getTimeUnit()));
            }
        }
    }

    /**
     * 基础解析
     *
     * @param json
     *            需要解析的json
     * @param path
     *            需要获取的路径
     * @param clazz
     *            解析类型
     * @param <T>
     * @return
     * @throws ExtJsonParseException
     */
    protected <T> T baseParse(String json, String path, Class<T> clazz, boolean isCustomPath)
        throws ExtJsonParseException {
        final boolean showLog = getShowLog();
        final Stopwatch stopwatch = showLog ? Stopwatch.createStarted() : null;
        try {
            DocumentContext parse = JsonPath.parse(json);
            path = isCustomPath ? path : ROOT_PREFIX.concat(SYMBOL_PREFIX).concat(path);
            return ObjectUtils.isEmpty(clazz) ? parse.read(path) : parse.read(path, clazz);
        } catch (Exception e) {
            throw new ExtJsonParseException(e.getMessage());
        } finally {
            if (showLog) {
                log.info("解析完毕,json:{},path:{},ClassName:{},耗时:{} ms", json, path, clazz.getName(),
                    stopwatch.elapsed(getTimeUnit()));
            }
        }
    }

    /**
     * 自定义设值
     *
     * @param json
     *            目标json
     * @param function
     *            自定义函数
     * @return
     * @throws ExtJsonParseException
     */
    public String putInCustom(String json, Function<DocumentContext, DocumentContext> function)
        throws ExtJsonParseException {
        final boolean showLog = getShowLog();
        final Stopwatch stopwatch = showLog ? Stopwatch.createStarted() : null;
        try {
            // DocumentContext为jsonpath上下文
            return function.apply(JsonPath.parse(json)).jsonString();
        } catch (Exception e) {
            throw new ExtJsonParseException(e.getMessage());
        } finally {
            if (showLog) {
                log.info("设置完毕,json:{},耗时:{} ms", json, stopwatch.elapsed(getTimeUnit()));
            }
        }
    }

    /**
     * 自定义获取操作
     *
     * @param json
     *            目标json
     * @param function
     *            自定义函数
     * @param <T>
     * @return
     * @throws ExtJsonParseException
     */
    public <T> T getForCustom(String json, Function<DocumentContext, T> function) throws ExtJsonParseException {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        if (StringUtils.isBlank(json)) {
            throw new ExtJsonParseException("目标参数[json]不能为空");
        }
        final boolean showLog = getShowLog();
        final Stopwatch stopwatch = showLog ? Stopwatch.createStarted() : null;
        try {
            // DocumentContext为jsonpath上下文
            return function.apply(JsonPath.parse(json));
        } catch (Exception e) {
            throw new ExtJsonParseException(e.getMessage());
        } finally {
            if (showLog) {
                log.info("解析完毕,json:{},耗时:{} ms", json, stopwatch.elapsed(getTimeUnit()));
            }
        }
    }

}

ExtJsonParseSupport

import cn.gov.zcy.service.exp.ExtJsonParseException;
import cn.gov.zcy.service.support.base.AbstractExtJsonParse;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * ExtJsonParseSupport
 *
 * @author Duansg
 * @version 1.0
 * @date 2021/11/17 下午4:55
 * @see cn.gov.zcy.item.test.common.ExtJsonParseSupportTest
 */
@Slf4j
@Builder
public final class ExtJsonParseSupport extends AbstractExtJsonParse {

    // 具体用法请见@see cn.gov.zcy.item.test.common.ExtJsonParseSupportTest

    /**
     * 解析耗时统计-时间单位
     */
    @Builder.Default
    private TimeUnit timeUnit = TimeUnit.MILLISECONDS;

    /**
     * 耗时日志开关
     */
    @Builder.Default
    private boolean showLog = false;

    /**
     * 获取根路径下的指定key的值,返回自定义类型
     *
     * @param json
     *            目标json
     * @param key
     *            指定键
     * @param valueType
     *            对应值的类型
     * @param <T>
     * @return
     * @throws ExtJsonParseException
     */
    public <T> T getForRoot(String json, String key, Class<T> valueType) throws ExtJsonParseException {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        if (StringUtils.isBlank(key)) {
            throw new ExtJsonParseException("目标参数[key]不能为空");
        }
        if (ObjectUtils.isEmpty(valueType)) {
            throw new ExtJsonParseException("目标参数[valueType]不能为空");
        }
        return super.baseParse(json, key, valueType, false);
    }

    /**
     * 获取根路径下的指定key的值,返回自定义类型
     *
     * @param json
     *            目标json
     * @param key
     *            指定键
     * @param valueType
     *            对应值的类型
     * @param <T>
     * @return
     */
    public <T> T getForRootIgnoreExcep(String json, String key, Class<T> valueType) {
        try {
            if (StringUtils.isBlank(json) || StringUtils.isBlank(key) || ObjectUtils.isEmpty(valueType)) {
                return null;
            }
            return super.baseParse(json, key, valueType, false);
        } catch (Exception e) {
            log.warn("json-path解析异常,此异常已忽略并返回null值,解析数据为:{},key为:{},type:{}", json, key, valueType.getName());
            return null;
        }
    }

    /**
     * 获取根路径下的指定key的值,返回自定义类型
     *
     * @param json
     *            目标json
     * @param key
     *            指定键
     * @param valueType
     *            对应值的类型
     * @param <T>
     * @return
     */
    public <T> T getForContainsRootIgnoreExcep(String json, String key, Class<T> valueType) {
        try {
            if (StringUtils.isBlank(json) || StringUtils.isBlank(key) || ObjectUtils.isEmpty(valueType)) {
                return null;
            }
            if (!json.contains(key)) {
                log.warn("json-path解析错误告警,此json中不包含key的信息,解析数据为:{},key为:{}", json, key);
                return null;
            }
            return super.baseParse(json, key, valueType, false);
        } catch (Exception e) {
            log.warn("json-path解析异常,此异常已忽略并返回null值,解析数据为:{},key为:{},type:{}", json, key, valueType.getName());
            return null;
        }
    }
    
    /**
     * 获取根路径下的指定key的值,返回object
     *
     * @param json
     *            目标json
     * @param key
     *            指定键
     * @return
     * @throws ExtJsonParseException
     */
    public Object getForRoot(String json, String key) throws ExtJsonParseException {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        if (StringUtils.isBlank(key)) {
            throw new ExtJsonParseException("目标参数[key]不能为空");
        }
        return super.baseParse(json, key, null, false);
    }

    /**
     * 获取指定路径下的指定key的值,返回object
     *
     * @param json
     *            目标json
     * @param path
     *            指定路径
     * @return
     * @throws ExtJsonParseException
     */
    public Object getForPath(String json, String path) throws ExtJsonParseException {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        if (StringUtils.isBlank(path)) {
            throw new ExtJsonParseException("目标参数[path]不能为空");
        }
        return super.baseParse(json, path, null, true);
    }

    /**
     * 获取指定路径下的指定key的值,返回自定义类型
     *
     * @param json
     *            目标json
     * @param path
     *            指定路径
     * @return
     * @throws ExtJsonParseException
     */
    public <T> T getForPath(String json, String path, Class<T> valueType) throws ExtJsonParseException {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        if (StringUtils.isBlank(path)) {
            throw new ExtJsonParseException("目标参数[json,path,key]不能为空");
        }
        return super.baseParse(json, path, valueType, true);
    }

    /**
     * 根路径下设置值,支持目标json为空
     *
     * @param json
     *            目标json
     * @param key
     *            设置键
     * @param value
     *            设置值
     * @return
     * @throws ExtJsonParseException
     */
    public String putInRoot(String json, String key, Object value) throws ExtJsonParseException {
        if (StringUtils.isBlank(key)) {
            throw new ExtJsonParseException("目标参数[key]不能为空");
        }
        if (ObjectUtils.isEmpty(value)) {
            throw new ExtJsonParseException("目标值[value]不能为空");
        }
        // 为空的话设置默认值
        json = StringUtils.isBlank(json) ? ROOT_EMPTY : json;
        return super.basePut(json, ROOT_PREFIX, new HashMap<String, Object>() {
            private static final long serialVersionUID = -6493253680889168520L;
            {
                put(key, value);
            }
        });
    }

    /**
     * 根路径下设置值,支持目标json为空
     *
     * @param json
     *            目标json
     * @param key
     *            设置键
     * @param value
     *            设置值
     * @return
     * @throws ExtJsonParseException
     */
    public String putInRootForMap(String json, Map<String, Object> values) throws ExtJsonParseException {
        if (CollectionUtils.isEmpty(values)) {
            throw new ExtJsonParseException("目标参数[values]不能为空");
        }
        // 为空的话设置默认值
        json = StringUtils.isBlank(json) ? ROOT_EMPTY : json;
        return super.basePut(json, ROOT_PREFIX, values);
    }
    
    /**
     * 指定路径下设置值,不支持目标json为空
     *
     * @param json
     *            目标json
     * @param path
     *            目标路径
     * @param key
     *            设置键
     * @param value
     *            设置值
     * @return
     * @throws ExtJsonParseException
     */
    public String putInPath(String json, String path, String key, Object value) throws ExtJsonParseException {
        if (StringUtils.isBlank(json) || StringUtils.isBlank(key) || StringUtils.isBlank(path)) {
            throw new ExtJsonParseException("目标参数[json,key,path]不能为空");
        }
        if (ObjectUtils.isEmpty(value)) {
            throw new ExtJsonParseException("目标值[value]不能为空");
        }
        return super.basePut(json, path, new HashMap<String, Object>() {
            private static final long serialVersionUID = -6493253680889168520L;
            {
                put(key, value);
            }
        });
    }

    @Override
    public TimeUnit getTimeUnit() {
        return this.timeUnit;
    }

    @Override
    protected boolean getShowLog() {
        return this.showLog;
    }
}

Test Unit

import cn.gov.zcy.service.exp.ExtJsonParseException;
import cn.gov.zcy.service.support.ExtJsonParseSupport;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.TimeUnit;

/**
 * ExtJsonParseSupportTest
 *
 * @author Duansg
 * @version 1.0
 * @date 2021/11/18 上午01:12
 */
@Slf4j
public class ExtJsonParseSupportTest {

    // 不要格式化此类!!!
    /**
     * {
     *   "from": 0,
     *   "size": 10,
     *   "timeout": "5000ms",
     *   "query": {
     *     "bool": {
     *       "filter": [
     *         {
     *           "term": {
     *             "currentAuditOrgId": {
     *               "value": 10001000259856,
     *               "boost": 1.0
     *             }
     *           }
     *         },
     *         {
     *           "terms": {
     *             "status": [
     *               0,
     *               1
     *             ],
     *             "boost": 1.0
     *           }
     *         },
     *         {
     *           "terms": {
     *             "currentAuditCode": [
     *               "zcy.agreement.center.goods.audit.prsecond",
     *               "zcy.agreement.center.goods.audit.prfirst",
     *               "zcy.agreement.center.goods.audit.prUnfreezeFirst",
     *               "zcy.agreement.center.goods.audit.prUnfreezeThird",
     *               "zcy.agreement.center.goods.audit.prUnfreezeSecond",
     *               "zcy.agreement.center.goods.audit.prthird"
     *             ],
     *             "boost": 1.0
     *           }
     *         }
     *       ],
     *       "adjust_pure_negative": true,
     *       "boost": 1.0
     *     }
     *   },
     *   "sort": [
     *     {
     *       "gmtApplied": {
     *         "order": "asc"
     *       }
     *     }
     *   ],
     *   "aggregations": {
     *     "aggCurrentAuditCode": {
     *       "terms": {
     *         "field": "currentAuditCode",
     *         "size": 12,
     *         "min_doc_count": 1,
     *         "shard_min_doc_count": 0,
     *         "show_term_doc_count_error": false,
     *         "execution_hint": "global_ordinals",
     *         "order": [
     *           {
     *             "_count": "desc"
     *           },
     *           {
     *             "_key": "asc"
     *           }
     *         ]
     *       }
     *     }
     *   }
     * }
     */
    private String json = "{\"from\":0,\"size\":10,\"timeout\":\"5000ms\",\"query\":{\"bool\":{\"filter\":[{\"term\":{\"currentAuditOrgId\":{\"value\":10001000259856,\"boost\":1.0}}},{\"terms\":{\"status\":[0,1],\"boost\":1.0}},{\"terms\":{\"currentAuditCode\":[\"zcy.agreement.center.goods.audit.prsecond\",\"zcy.agreement.center.goods.audit.prfirst\",\"zcy.agreement.center.goods.audit.prUnfreezeFirst\",\"zcy.agreement.center.goods.audit.prUnfreezeThird\",\"zcy.agreement.center.goods.audit.prUnfreezeSecond\",\"zcy.agreement.center.goods.audit.prthird\"],\"boost\":1.0}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"sort\":[{\"gmtApplied\":{\"order\":\"asc\"}}],\"aggregations\":{\"aggCurrentAuditCode\":{\"terms\":{\"field\":\"currentAuditCode\",\"size\":12,\"min_doc_count\":1,\"shard_min_doc_count\":0,\"show_term_doc_count_error\":false,\"execution_hint\":\"global_ordinals\",\"order\":[{\"_count\":\"desc\"},{\"_key\":\"asc\"}]}}}}";
    @Test
    public void _获取根路径下的指定key的值_指定类型() {
        try {
            Integer value = ExtJsonParseSupport.builder().build().getForRoot(json, "fraaaaom", Integer.class);
            log.info("_获取根路径下的指定key的值_指定类型:{}", value);
            // 00:11:07.589 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - _获取根路径下的指定key的值_指定类型:0
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void _获取根路径下的指定key的值_Object() {
        try {
            Object value = ExtJsonParseSupport.builder().build().getForRoot(json, "timeout");
            String printValue = (String) value;
            log.info("_获取根路径下的指定key的值_Object:{}", printValue);
            // 00:14:27.221 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - _获取根路径下的指定key的值_Object:5000ms
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void _获取指定路径下的指定key的值_Object() {
        try {
            /*
             Object v1 = ExtJsonParseSupport.builder().build().getForPath(json, "$.query.bool.filter");
             Object v1_1 = ExtJsonParseSupport.builder().build().getForPath(json, "$.query.bool.filter[*]");
              List printValue = (List)v1;
              List printValue = (List)v1_1;
            log: _获取指定路径下的指定key的值_Object:[{"term":{"currentAuditOrgId":{"value":10001000259856,"boost":1.0}}},{"terms":{"status":[0,1],"boost":1.0}},{"terms":{"currentAuditCode":["zcy.agreement.center.goods.audit.prsecond","zcy.agreement.center.goods.audit.prfirst","zcy.agreement.center.goods.audit.prUnfreezeFirst","zcy.agreement.center.goods.audit.prUnfreezeThird","zcy.agreement.center.goods.audit.prUnfreezeSecond","zcy.agreement.center.goods.audit.prthird"],"boost":1.0}}]
             */
            // -----------------
            /*
              Object v2 = ExtJsonParseSupport.builder().build().getForPath(json, "$.query.bool.filter[1]");
            Map printValue = (Map)v2;
            log:00:21:46.540 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - _获取指定路径下的指定key的值_Object:{terms={status=[0,1], boost=1.0}}
             */

            Object v2 = ExtJsonParseSupport.builder().build().getForPath(json,
                "$.query.bool.filter[0].term.currentAuditOrgId.value");
            // 00:28:41.298 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - _获取指定路径下的指定key的值_Object:10001000259856
            log.info("_获取指定路径下的指定key的值_Object:{}", v2);
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void _获取指定路径下的指定key的值_自定义类型() {
        try {
            // 其他用法同上 @see _获取指定路径下的指定key的值_Object testMethod
            Long value = ExtJsonParseSupport.builder().build().getForPath(json,
                "$.query.bool.filter[0].term.currentAuditOrgId.value", Long.class);
            log.info("_获取指定路径下的指定key的值_自定义类型:{}", value);
            // 00:31:57.411 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - _获取指定路径下的指定key的值_自定义类型:10001000259856
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void 自定义获取操作() {

        try {
            Long value =
                ExtJsonParseSupport.builder().build().getForCustom(json, documentContext -> {
                    Object v1 = documentContext.read("$.query.bool.filter[0].term.currentAuditOrgId.value");
                    Long v2 =
                        documentContext.read("$.query.bool.filter[0].term.currentAuditOrgId.value", Long.class);
                    log.info("自定义获取操作_v1:{}", v1);
                    log.info("自定义获取操作_v2:{}", v2);
                    return v2;
                });
            log.info("自定义获取操作:{}", value);
            /*
            00:35:22.924 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - 自定义获取操作_v1:10001000259856
            00:35:22.924 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - 自定义获取操作_v2:10001000259856
            00:35:22.924 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - 自定义获取操作:10001000259856
             */
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }


    @Test
    public void _根路径下设置值() {
        try {
            String v1 = ExtJsonParseSupport.builder().build().putInRoot("", "Duansg_v1", "hhhh");
            String v2 = ExtJsonParseSupport.builder().build().putInRoot(null, "Duansg_v2", "gggg");
            log.info("_根路径下设置值,v1:{},v2:{}", v1, v2);
            /*
            00:40:39.375 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - _根路径下设置值,v1:{"Duansg_v1":"hhhh"},v2:{"Duansg_v2":"gggg"}
             */
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void _指定路径下设置值() {
        try {
            String tempJson = "{\"item\":{\"name\":\"hhh\"}}";
            String s = ExtJsonParseSupport.builder().build().putInPath(tempJson, "$", "Duansg_v1", "hhhh");
            log.info(s);
            /*
            00:45:12.969 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest -
             {"item":{"name":"hhh"},"Duansg_v1":"hhhh"}
             */
            String s1 = ExtJsonParseSupport.builder().build().putInPath(s, "$.item", "Duansg_v2", "ggg");
            log.info(s1);
            /*
            00:45:12.970 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest -
             {"item":{"name":"hhh","Duansg_v2":"ggg"},"Duansg_v1":"hhhh"}
             */
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void _自定义设值() {
        String tempJson = "{\"item\":{\"name\":\"hhh\"}}";

        try {
            String s = ExtJsonParseSupport.builder().build().putInCustom(tempJson, documentContext -> {
                documentContext.put("$", "Duansg_v1", "hhhh");
                documentContext.put("$.item", "Duansg_v2", "ggg");
                return documentContext;
            });
            log.info(s);
            /*
            00:48:42.546 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest
            - {"item":{"name":"hhh","Duansg_v2":"ggg"},"Duansg_v1":"hhhh"}
             */
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }
    /**
     * 以下为成员变量的使用方法
     */
    @Test
    public void _耗时与开关() {
        String tempJson = "{\"item\":{\"name\":\"hhh\"}}";
        try {
            // 如果解析比较大的json,建议将开关在调用方设置动态配置进行获取,
            String s = ExtJsonParseSupport.builder().timeUnit(TimeUnit.MILLISECONDS).showLog(true).build()
                .putInCustom(tempJson, documentContext -> {
                    documentContext.put("$", "Duansg_v1", "hhhh");
                    documentContext.put("$.item", "Duansg_v2", "ggg");
                    return documentContext;
                });
            log.info(s);
            /*
            01:09:25.266 [main] INFO cn.gov.zcy.service.support.base.AbstractExtJsonParse - 设置完毕,json:{"item":{"name":"hhh"}},耗时:133 ms
            01:09:25.266 [main] INFO cn.gov.zcy.item.test.common.ExtJsonParseSupportTest - {"item":{"name":"hhh","Duansg_v2":"ggg"},"Duansg_v1":"hhhh"}
             */
        } catch (ExtJsonParseException e) {
            e.printStackTrace();
        }
    }

}
相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
|
3月前
|
Go 索引
internal\model\data_support.go:17:10: cannot use _ as value or type
internal\model\data_support.go:17:10: cannot use _ as value or type
Warning: To load an ES module, set “type“: “module“ in the package.json or use the .mjs extension.
Warning: To load an ES module, set “type“: “module“ in the package.json or use the .mjs extension.
|
5月前
tasks.json、launch.json、c_cpp_properties.json配置
tasks.json、launch.json、c_cpp_properties.json配置
79 0
|
6月前
|
Java
Found multiple occurrences of org.json.JSONObject on the class path:
Found multiple occurrences of org.json.JSONObject on the class path:
120 0
poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
369 0
|
7月前
|
JSON NoSQL Redis
ruoyi-nbcio发送消息的SerializationException: Could not read JSON: Unexpected character (‘¬‘ (code 172))
ruoyi-nbcio发送消息的SerializationException: Could not read JSON: Unexpected character (‘¬‘ (code 172))
172 0
org.activiti.engine.ActivitiException: Couldn't deserialize object in variable 'application'
org.activiti.engine.ActivitiException: Couldn't deserialize object in variable 'application'
|
资源调度
error This module isn‘t specified in a package.json file.
error This module isn‘t specified in a package.json file.
ERROR Plugin load failed: hexo-generator-json-content
ERROR Plugin load failed: hexo-generator-json-content
68 0
使用pageHelper报错 Type definition error: [simple type, classXXXX]
使用pageHelper报错 Type definition error: [simple type, classXXXX]