最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中json處理工具JsonPath的使用教程

 更新時(shí)間:2023年08月30日 11:38:32   作者:movee  
JsonPath類似于XPath,是一種json數(shù)據(jù)結(jié)構(gòu)節(jié)點(diǎn)定位和導(dǎo)航表達(dá)式語言,這篇文章主要為大家介紹了JsonPath的基本使用,需要的小伙伴可以參考下

最近在思考構(gòu)建一個(gè)服務(wù)編排(Service Orchestration)系統(tǒng),考慮這個(gè)系統(tǒng)至少需要具備以下特征:

使用統(tǒng)一的方法定義服務(wù)功能單元

使用一種通用的方式將一個(gè)或多個(gè)服務(wù)的輸出映射到下游服務(wù)的輸入,映射時(shí)支持基礎(chǔ)的數(shù)據(jù)轉(zhuǎn)換與處理

支持以搭積木的方式將低層服務(wù)功能單元組織成更高層抽象的服務(wù)功能,直至一個(gè)完整的服務(wù)

用戶編排服務(wù)時(shí),具備較大的靈活性定制業(yè)務(wù)

1 JsonPath是什么

json本質(zhì)上是一個(gè)樹形數(shù)據(jù)結(jié)構(gòu),同樣作為典型樹形數(shù)據(jù)結(jié)構(gòu)的xml文檔有XPathXML Path Language)這種廣泛使用的定位和選擇節(jié)點(diǎn)的表達(dá)式語言,java對(duì)象也有OGNLObject-Graph Navigation Language)這種對(duì)象屬性定位和導(dǎo)航表達(dá)式語言,JsonPath類似于XPath,是一種json數(shù)據(jù)結(jié)構(gòu)節(jié)點(diǎn)定位和導(dǎo)航表達(dá)式語言。

2 JsonPath的基本使用

2.1 JsonPath依賴

要使用JsonPath,需要在pom.xml文件中添加相應(yīng)的依賴:

2.2 json測(cè)試數(shù)據(jù)

為了便于說明,本文用到的json測(cè)試數(shù)據(jù),如果沒有特別說明,使用以下的json數(shù)據(jù):

{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 12.99
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 8.99
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    },
    "expensive": 10
}

2.3 讀取json內(nèi)容

需要獲取指定json指定節(jié)點(diǎn)的數(shù)據(jù),提供json字符串和JsonPath表達(dá)式即可:

    // 讀取json字符串的expensive葉子節(jié)點(diǎn)的值
    Object expensive = JsonPath.read(jsonStr, "$.expensive");
    log.info("expensive value: {}, class: {}", expensive, expensive.getClass().getCanonicalName());
    // 讀取json字符串store節(jié)點(diǎn)下bicycle節(jié)點(diǎn)的值
    Object bicycle = JsonPath.read(jsonStr, "$.store.bicycle");
    log.info("bicycle value: {}, class: {}", bicycle, bicycle.getClass().getCanonicalName());
    // 讀取json字符串store下第一個(gè)book節(jié)點(diǎn)的值
    Object book = JsonPath.read(jsonStr, "$.store.book[0]");
    log.info("book value: {}, class: {}", book, book.getClass().getCanonicalName());
    // 讀取json字符串所有的author后代節(jié)點(diǎn)的值
    Object authors = JsonPath.read(jsonStr, "$..author");
    log.info("authors value: {}, class: {}", authors, authors.getClass().getCanonicalName());
    // 讀取json字符串中所有price值小于10的值
    Object books = JsonPath.read(jsonStr, "$.store.book[?(@.price < 10)]");
    log.info("books value: {}, class: {}", books, books.getClass().getCanonicalName());

輸出如下日志:

expensive value: 10, class: java.lang.Integer
bicycle value: {color=red, price=19.95}, class: java.util.LinkedHashMap
book value: {category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95}, class: java.util.LinkedHashMap
authors value: ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"], class: net.minidev.json.JSONArray
books value: [{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}], class: net.minidev.json.JSONArray

2.3.1 基本語法

在JsonPath表達(dá)式語法中,$表示json頂層節(jié)點(diǎn),.表示直接孩子,所以$.expensive表示json字符串的直接孩子節(jié)點(diǎn)expensive,節(jié)點(diǎn)也可以用[]表示。所以$['expensive']$.expensive等價(jià)。如果[]中是數(shù)字,則表示數(shù)組的某個(gè)元素,所以$.store.book[0]表示第1本書。數(shù)組支持切片,$.store.book[0:3]表示第1本到第3本書。..則表示任意的后代。*則表示所有的子節(jié)點(diǎn)。綜合起來如下表所示:

OperatorDescription
$The root element to query. This starts all path expressions.
@The current node being processed by a filter predicate.
*Wildcard. Available anywhere a name or numeric are required.
..Deep scan. Available anywhere a name is required.
.<name>Dot-notated child
['<name>' (, '<name>')]Bracket-notated child or children
[<number> (, <number>)]Array index or indexes
[start:end]Array slice operator
[?(<expression>)]Filter expression. Expression must evaluate to a boolean value.

JsonPath還支持根據(jù)條件過濾,表達(dá)式[?(expression)]中括號(hào)內(nèi)為條件表達(dá)式。表達(dá)式$.store.book[?(@.price < 10)]@表示遍歷到的當(dāng)前book,整個(gè)表達(dá)式就表示store中價(jià)格小于10的所有的book。

JsonPath的條件表達(dá)式支持以下操作符:

OperatorDescription
==left is equal to right (note that 1 is not equal to '1')
!=left is not equal to right
<left is less than right
<=left is less or equal to right
left is greater than right
>=left is greater than or equal to right
=~left matches regular expression [?(@.name =~ /foo.*?/i)]
inleft exists in right [?(@.size in ['S', 'M'])]
ninleft does not exists in right
subsetofleft is a subset of right [?(@.sizes subsetof ['S', 'M', 'L'])]
anyofleft has an intersection with right [?(@.sizes anyof ['M', 'L'])]
noneofleft has no intersection with right [?(@.sizes noneof ['M', 'L'])]
sizesize of left (array or string) should match right
emptyleft (array or string) should be empty

當(dāng)然一些常用的filter函數(shù)也是要支持的:

FunctionDescriptionOutput type
min()Provides the min value of an array of numbersDouble
max()Provides the max value of an array of numbersDouble
avg()Provides the average value of an array of numbersDouble
stddev()Provides the standard deviation value of an array of numbersDouble
length()Provides the length of an arrayInteger
sum()Provides the sum value of an array of numbersDouble
keys()Provides the property keys (An alternative for terminal tilde ~)Set<E>
concat(X)Provides a concatinated version of the path output with a new itemlike input
append(X)add an item to the json path output arraylike input
first()Provides the first item of an arrayDepends on the array
last()Provides the last item of an arrayDepends on the array
index(X)Provides the item of an array of index: X, if the X is negative, take from backwardsDepends on the array
Filter Operators

詳細(xì)的JsonPath表達(dá)式語法和支持的過濾條件請(qǐng)參考github官方文檔,文檔本身介紹的已經(jīng)很詳細(xì)了。

2.3.2 返回值

從上面的日志結(jié)果來看,JsonPath的返回結(jié)果的數(shù)據(jù)類型依情況而定,大概情況是(具體實(shí)際情況與底層使用的Json處理組件相關(guān)):

  • 如果結(jié)果是json葉子節(jié)點(diǎn),則是葉子節(jié)點(diǎn)對(duì)應(yīng)的基本數(shù)據(jù)類型
  • 如果是數(shù)組,則是JSONArray
  • 如果是對(duì)象,這是LinkedHashMap

2.3.3 指定返回值類型

JsonPath也支持指定返回值類型,類似于json反序列化

Long expensive = JsonPath.parse(jsonStr).read("$.expensive", Long.class);
Bicycle bicycle = JsonPath.parse(jsonStr).read("$.store.bicycle", Bicycle.class);

如果json底層處理組件是jackson或gson,還可以支持泛型,假如使用jackson,先添加jackson-databind依賴:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>

然后配置使用jackson進(jìn)行json處理和映射即可,如下所示:

Configuration.setDefaults(new Configuration.Defaults() {
    // 底層使用jackson
    private final JsonProvider jsonProvider = new JacksonJsonProvider();
    private final MappingProvider mappingProvider = new JacksonMappingProvider();
    @Override
    public JsonProvider jsonProvider() {
        return jsonProvider;
    }
    @Override
    public MappingProvider mappingProvider() {
        return mappingProvider;
    }
    @Override
    public Set<Option> options() {
        return EnumSet.noneOf(Option.class);
    }
});
TypeRef<List<String>> typeRef = new TypeRef<List<String>>() {};
List<String> authors = JsonPath.parse(jsonStr).read("$..author", typeRef);

2.4 修改json的值

2.4.1 為節(jié)點(diǎn)設(shè)置新值

Object book = JsonPath.read(jsonStr, "$.store.book[0]");
String target = "{\"x\": 128}";
String modified = JsonPath.parse(target).set("$.x", book).jsonString();

輸出:

modified: {"x":{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95}}

可見目標(biāo)json字符串的節(jié)點(diǎn)x的值替換為了book的值,新的值與原先的值可以是完全不同的類型

2.4.2 為對(duì)象節(jié)點(diǎn)添加新的子節(jié)點(diǎn)

下面的例子為target json字符串添加了一個(gè)名字為k的子節(jié)點(diǎn)。注意,這個(gè)方法只能作用于json對(duì)象,不能是葉子節(jié)點(diǎn)或數(shù)組

Object book = JsonPath.read(jsonStr, "$.store.book[0]");
String target = "{\"x\": 128}";
String modified = JsonPath.parse(target).put("$", "k", book).jsonString();

2.4.3 對(duì)數(shù)組添加新的元素

String target = "{\"x\": [128]}";
String modified = JsonPath.parse(target).put("$.x", 300).jsonString();

2.4.4 重命名節(jié)點(diǎn)名字

String target = "{\"x\": [128]}";
String modified = JsonPath.parse(target).renameKey("$", "x", "y").jsonString();

2.4.5 刪除

String target = "{\"x\": [128]}";
String modified = JsonPath.parse(target).delete("$.x").jsonString();

3 JsonPath的高級(jí)特性

3.1 進(jìn)一步配置你的JsonPath

JsonPath提供了一些配置項(xiàng)來調(diào)整它的功能,這些配置項(xiàng)配置在Option枚舉類中,如下所示:

public enum Option {
    DEFAULT_PATH_LEAF_TO_NULL,
    ALWAYS_RETURN_LIST,
    AS_PATH_LIST,
    SUPPRESS_EXCEPTIONS,
    REQUIRE_PROPERTIES
}

功能說明:

  • DEFAULT_PATH_LEAF_TO_NULL:當(dāng)路徑表達(dá)的節(jié)點(diǎn)不存在時(shí),不拋出異常,而是返回null值
  • ALWAYS_RETURN_LIST:返回值總是一個(gè)list,即使路徑找到的是單個(gè)值
  • AS_PATH_LIST:返回找到節(jié)點(diǎn)的路徑,而不是節(jié)點(diǎn)的值
  • SUPPRESS_EXCEPTIONS:異常時(shí)不拋出異常

使用配置:

Configuration conf = Configuration.builder()
   .options(Option.AS_PATH_LIST).build();
List<String> pathList = JsonPath.using(conf).parse(jsonStr).read("$..author");
// 返回的是author節(jié)點(diǎn)的路徑列表
assertThat(pathList).containsExactly(
    "$['store']['book'][0]['author']",
    "$['store']['book'][1]['author']",
    "$['store']['book'][2]['author']",
    "$['store']['book'][3]['author']");

3.2 修改json底層處理組件

JsonPath支持多個(gè)json組件,默認(rèn)使用的是JsonSmartJsonProvider,其他的還包括:

JacksonJsonProvider
JacksonJsonNodeJsonProvider
GsonJsonProvider
JsonOrgJsonProvider
JakartaJsonProvider

使用下面的方式可以修改默認(rèn)的json provider:

Configuration.setDefaults(new Configuration.Defaults() {
    private final JsonProvider jsonProvider = new JacksonJsonProvider();
    private final MappingProvider mappingProvider = new JacksonMappingProvider();
    @Override
    public JsonProvider jsonProvider() {
        return jsonProvider;
    }
    @Override
    public MappingProvider mappingProvider() {
        return mappingProvider;
    }
    @Override
    public Set<Option> options() {
        return EnumSet.noneOf(Option.class);
    }
});

3.3 性能優(yōu)化

如下的方式每次都需要解析json字符串:

Object book = JsonPath.read(jsonStr, "$.store.book[0]");

可以先解析json字符串,然后在查找,這樣只需要解析一次:

DocumentContext context = JsonPath.parse(jsonStr)
Long expensive = context.read("$.expensive", Long.class);
Bicycle bicycle = context.read("$.store.bicycle", Bicycle.class);

還可以使用cache,JsonPath已經(jīng)提供了兩個(gè)cache:

com.jayway.jsonpath.spi.cache.LRUCache (default, thread safe)
com.jayway.jsonpath.spi.cache.NOOPCache (no cache)

我們可以這樣配置使用cache:

CacheProvider.setCache(new LRUCache(100));

或者配置一個(gè)我們自己實(shí)現(xiàn)的cache:

CacheProvider.setCache(new Cache() {
    //Not thread safe simple cache
    private Map<String, JsonPath> map = new HashMap<String, JsonPath>();
    @Override
    public JsonPath get(String key) {
        return map.get(key);
    }
    @Override
    public void put(String key, JsonPath jsonPath) {
        map.put(key, jsonPath);
    }
});

到此這篇關(guān)于Java中json處理工具JsonPath的使用教程的文章就介紹到這了,更多相關(guān)Java JsonPath內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis基于TypeHandler實(shí)現(xiàn)敏感數(shù)據(jù)加密

    Mybatis基于TypeHandler實(shí)現(xiàn)敏感數(shù)據(jù)加密

    業(yè)務(wù)場(chǎng)景中經(jīng)常會(huì)遇到諸如用戶手機(jī)號(hào),身份證號(hào),銀行卡號(hào),郵箱,地址,密碼等等信息,屬于敏感信息,本文就來介紹一下Mybatis基于TypeHandler實(shí)現(xiàn)敏感數(shù)據(jù)加密,感興趣的可以了解一下
    2023-10-10
  • Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別)

    Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別)

    這篇文章主要介紹了Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別) ,需要的朋友可以參考下
    2017-02-02
  • Java實(shí)現(xiàn)可視化走迷宮小游戲的示例代碼

    Java實(shí)現(xiàn)可視化走迷宮小游戲的示例代碼

    這篇文章主要介紹了Java如何實(shí)現(xiàn)可視化走迷宮小游戲。本程序適用于java程序員鞏固類與對(duì)象、文件讀取、事件響應(yīng)、awt包中各種工具的相關(guān)概念以及對(duì)邏輯能力的鍛煉,需要的可以參考一下
    2022-11-11
  • Idea 自動(dòng)生成測(cè)試的實(shí)現(xiàn)步驟

    Idea 自動(dòng)生成測(cè)試的實(shí)現(xiàn)步驟

    當(dāng)我們?cè)趯懲暌恍┙涌诜椒ê笮枰獪y(cè)試時(shí),一個(gè)一個(gè)新建測(cè)試類比較麻煩 idea給我們提供了快捷辦法,本文主要介紹了Idea 自動(dòng)生成測(cè)試的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • MybatisPlus的LambdaQueryWrapper用法詳解

    MybatisPlus的LambdaQueryWrapper用法詳解

    LambdaQueryWrapper<Tag>?是 MyBatis-Plus 框架中的一個(gè)功能強(qiáng)大的查詢構(gòu)造器,它用于構(gòu)建 SQL 查詢條件,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-10-10
  • Java實(shí)現(xiàn)五子棋游戲

    Java實(shí)現(xiàn)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Java將RTF轉(zhuǎn)換為PDF格式的實(shí)現(xiàn)

    Java將RTF轉(zhuǎn)換為PDF格式的實(shí)現(xiàn)

    本文主要介紹了Java將RTF轉(zhuǎn)換為PDF格式的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 利用java實(shí)現(xiàn)單詞倒序排列

    利用java實(shí)現(xiàn)單詞倒序排列

    這篇文章就是利用java實(shí)現(xiàn)單詞倒序排列,感覺像是在變魔術(shù),感興趣的小伙伴來見證一下
    2015-07-07
  • MyBatis-plus使用lambda條件構(gòu)造器報(bào)錯(cuò)問題及解決

    MyBatis-plus使用lambda條件構(gòu)造器報(bào)錯(cuò)問題及解決

    這篇文章主要介紹了MyBatis-plus使用lambda條件構(gòu)造器報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 解決Callable的對(duì)象中,用@Autowired注入別的對(duì)象失敗問題

    解決Callable的對(duì)象中,用@Autowired注入別的對(duì)象失敗問題

    這篇文章主要介紹了解決Callable的對(duì)象中,用@Autowired注入別的對(duì)象失敗問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論

新绛县| 仁怀市| 环江| 五大连池市| 连云港市| 高要市| 宜兴市| 兴海县| 万安县| 林口县| 道真| 肥城市| 大港区| 武隆县| 仙居县| 阿拉尔市| 德令哈市| 镇平县| 赤水市| 普兰县| 双辽市| 梓潼县| 噶尔县| 安康市| 基隆市| 股票| 汉沽区| 靖边县| 宣武区| 本溪市| 镇宁| 阳东县| 新泰市| 卢湾区| 隆化县| 武威市| 荣昌县| 东阳市| 顺平县| 马关县| 响水县|