当前位置: 代码网 > it编程>编程语言>Java > SpringBoot使用JSONPath实现高效处理JSON数据

SpringBoot使用JSONPath实现高效处理JSON数据

2026年01月15日 Java 我要评论
前言在日常开发中,我们经常需要处理 json 数据,特别是从复杂的 json 结构中提取特定字段。传统的处理方式如 gson、jackson 的 api 虽然功能强大,但在处理复杂路径提取时代码往往显

前言

在日常开发中,我们经常需要处理 json 数据,特别是从复杂的 json 结构中提取特定字段。传统的处理方式如 gson、jackson 的 api 虽然功能强大,但在处理复杂路径提取时代码往往显得冗长且不易维护。

今天给大家介绍一个更优雅的解决方案 —— jsonpath,它就像 json 界的 xpath,让我们可以用简洁的路径表达式来定位和提取 json 数据。

什么是 jsonpath

jsonpath 是一种用于从 json 文档中提取特定数据的查询语言。它的语法简洁直观,类似于 javascript 对象属性的访问方式。

常用 jsonpath 语法

表达式说明
$根节点
@当前节点
. 或 []子节点操作符
..递归下降(任意深度)
*通配符,匹配所有成员/元素
[]下标运算符
[start:end]数组切片
[?()]过滤表达式

spring boot 集成 jsonpath

1. 添加依赖

pom.xml 中添加 jsonpath 依赖:

<dependency>
    <groupid>com.jayway.jsonpath</groupid>
    <artifactid>json-path</artifactid>
    <version>2.9.0</version>
</dependency>

2. 基础使用示例

首先准备一个 json 示例:

{
  "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
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

读取数据

import com.jayway.jsonpath.jsonpath;
import com.jayway.jsonpath.documentcontext;
import com.jayway.jsonpath.pathnotfoundexception;

public class jsonpathexample {

    private string json = "..."; // 上述 json 字符串

    @test
    public void testreadjson() {
        // 获取所有书籍的作者
        list<string> authors = jsonpath.parse(json)
            .read("$.store.book[*].author");

        // 获取第一本书的价格
        double price = jsonpath.parse(json)
            .read("$.store.book[0].price");

        // 获取所有价格低于10元的书籍
        list<map> cheapbooks = jsonpath.parse(json)
            .read("$.store.book[?(@.price < 10)]");

        // 获取最后一本书
        map lastbook = jsonpath.parse(json)
            .read("$.store.book[-1]");
    }
}

在 spring boot 中的实际应用

import org.springframework.web.bind.annotation.*;
import com.jayway.jsonpath.jsonpath;

@restcontroller
@requestmapping("/api")
public class bookcontroller {

    @postmapping("/extract")
    public responseentity<?> extractdata(@requestbody string jsonstring) {
        try {
            // 提取所有书籍标题
            list<string> titles = jsonpath.parse(jsonstring)
                .read("$.store.book[*].title");

            // 提取价格区间内的书籍
            list<map> books = jsonpath.parse(jsonstring)
                .read("$.store.book[?(@.price >= 8 && @.price <= 12)]");

            return responseentity.ok(map.of(
                "titles", titles,
                "filteredbooks", books
            ));
        } catch (pathnotfoundexception e) {
            return responseentity.badrequest()
                .body("json路径不存在: " + e.getmessage());
        }
    }

    @getmapping("/authors")
    public responseentity<?> getauthors(@requestparam string jsondata) {
        list<string> authors = jsonpath.parse(jsondata)
            .read("$.store.book[*].author");
        return responseentity.ok(authors);
    }
}

3. 高级用法

自定义配置

import com.jayway.jsonpath.configuration;
import com.jayway.jsonpath.option;

@configuration
public class jsonpathconfig {

    public configuration jsonpathconfiguration() {
        return configuration.builder()
            // 抑制异常,返回 null
            .options(option.suppress_exceptions)
            // 默认值为空集合
            .options(option.default_path_leaf_to_null)
            // 总是返回列表
            .options(option.always_return_list)
            // 缓存
            .options(option.cache)
            .build();
    }
}

缓存解析结果

@service
public class jsonpathcacheservice {

    private final map<string, object> cache = new concurrenthashmap<>();

    public object readwithcache(string json, string path) {
        return jsonpath.using(configuration.defaultconfiguration())
            .parse(json)
            .read(path);
    }

    // 预编译路径,提升性能
    private final jsonpath compiledpath = jsonpath.compile("$.store.book[*]");

    public list<map> readoptimized(string json) {
        return compiledpath.read(json);
    }
}

与 rest 调用结合

@service
public class externalapiservice {

    private final resttemplate resttemplate;

    public list<string> extractfromexternalapi(string url, string jsonpath) {
        string response = resttemplate.getforobject(url, string.class);
        return jsonpath.parse(response).read(jsonpath);
    }
}

过滤表达式详解

// 价格大于10的书籍
$.store.book[?(@.price > 10)]

// category 为 fiction 的书籍
$.store.book[?(@.category == 'fiction')]

// 包含 isbn 字段的书籍
$.store.book[?(@.isbn)]

// 正则匹配
$.store.book[?(@.author =~ /.*melville.*/)]

// 多条件组合
$.store.book[?(@.price < 10 && @.category == 'fiction')]

除了 jayway jsonpath,常见的 json 处理库也有各自的 jsonpath 或类似功能实现。

fastjson - 内置 jsonpath

fastjson内置了 jsonpath 支持,使用起来非常简洁。

添加依赖

<dependency>
    <groupid>com.alibaba.fastjson2</groupid>
    <artifactid>fastjson2</artifactid>
    <version>2.0.53</version>
</dependency>

使用示例

import com.alibaba.fastjson2.json;
import com.alibaba.fastjson2.jsonpath;
import com.alibaba.fastjson2.jsonobject;

public class fastjsonpathexample {

    private string json = "..."; // 同上 json 示例

    @test
    public void testfastjsonpath() {
        jsonobject object = json.parseobject(json);

        // 获取所有书籍作者
        list<string> authors = (list<string>) jsonpath.eval(object, "$.store.book[*].author");

        // 获取第一本书价格
        double price = (double) jsonpath.eval(object, "$.store.book[0].price");

        // 过滤价格小于10的书籍
        list books = (list) jsonpath.eval(object, "$.store.book[?(@.price < 10)]");

        // size 方法
        integer size = (integer) jsonpath.eval(object, "$.store.book.size()");

        // 获取所有包含 isbn 的书籍
        list bookswithisbn = (list) jsonpath.eval(object, "$.store.book[?(@.isbn)]");
    }
}

fastjson jsonpath 多种查询方式

fastjson 提供了多种查询方式,适应不同场景:

import com.alibaba.fastjson2.json;
import com.alibaba.fastjson2.jsonpath;
import com.alibaba.fastjson2.jsonobject;

public class fastjsonpathqueryexample {

    private jsonobject object = json.parseobject(json);

    @test
    public void testdifferentquerymethods() {

        // ========== 方式一:jsonpath.eval(静态方法,最常用)==========
        list authors1 = (list) jsonpath.eval(object, "$.store.book[*].author");


        // ========== 方式二:jsonpath.of + extract(推荐,性能更好)==========
        // 预编译路径表达式,性能更优(适合重复使用)
        jsonpath path = jsonpath.of("$.store.book[*].author");
        list authors2 = (list) path.extract(object);


        // ========== 方式三:compile + eval(另一种编译方式)==========
        jsonpath compiledpath = jsonpath.compile("$.store.book[*].author");
        list authors3 = (list) compiledpath.eval(object);


        // ========== 方式四:路径对象直接调用 set(修改操作)==========
        jsonpath pricepath = jsonpath.of("$.store.book[0].price");
        pricepath.set(object, 88.88);


        // ========== 方式五:contains(判断是否包含路径)==========
        boolean hasbook = jsonpath.contains(object, "$.store.book");
        boolean hasisbn = jsonpath.contains(object, "$.store.book[2].isbn");


        // ========== 方式六:size(获取数组大小)==========
        integer arraysize = (integer) jsonpath.eval(object, "$.store.book.size()");
        // 或者使用编译后的路径
        jsonpath sizepath = jsonpath.of("$.store.book.size()");
        integer size = (integer) sizepath.eval(object);
    }
}

fastjson jsonpath 修改操作

fastjson 的 jsonpath 不仅可以读取数据,还支持修改数据,这是它的一个强大特性。

import com.alibaba.fastjson2.json;
import com.alibaba.fastjson2.jsonpath;
import com.alibaba.fastjson2.jsonobject;

public class fastjsonpathmodifyexample {

    @test
    public void testjsonpathset() {
        jsonobject object = json.parseobject(json);

        // 修改第一本书的价格
        jsonpath.set(object, "$.store.book[0].price", 99.99);

        // 修改自行车的颜色
        jsonpath.set(object, "$.store.bicycle.color", "blue");

        // 批量修改所有书籍价格
        jsonpath.set(object, "$.store.book[*].price", 15.88);

        // 修改包含 isbn 的书籍的 category
        jsonpath.set(object, "$.store.book[?(@.isbn)].category", "classic");

        // 添加新字段
        jsonpath.set(object, "$.store.book[0].publisher", "tech press");

        // 数组末尾添加元素(通过路径获取数组后操作)
        jsonarray bookarray = (jsonarray) jsonpath.eval(object, "$.store.book");
        bookarray.add(json.parseobject("{\"title\":\"new book\",\"price\":9.99}"));

        // 删除字段
        jsonpath.remove(object, "$.store.bicycle");

        system.out.println(json.tojsonstring(object));
    }
}

fastjson jsonpath 其他操作

// 获取集合大小
integer size = (integer) jsonpath.eval(object, "$.store.book.size()");

// 获取集合第一个
object first = jsonpath.eval(object, "$.store.book.first()");

// 获取集合最后一个
object last = jsonpath.eval(object, "$.store.book.last()");

// 获取属性所有值
collection values = (collection) jsonpath.eval(object, "$.store.book.values()");

jackson - jsonpointer / jackson jsonpath

jackson 原生支持 jsonpointer (rfc 6901),但不是完整的 jsonpath 实现。若要使用 jsonpath 功能,可以通过以下两种方式:

方式一:使用 jsonpointer(原生支持)

<dependency>
    <groupid>com.fasterxml.jackson.core</groupid>
    <artifactid>jackson-databind</artifactid>
    <version>2.18.2</version>
</dependency>
import com.fasterxml.jackson.databind.jsonnode;
import com.fasterxml.jackson.databind.objectmapper;
import com.fasterxml.jackson.core.jsonpointer;

public class jacksonjsonpointerexample {

    private string json = "...";
    private objectmapper mapper = new objectmapper();

    @test
    public void testjsonpointer() throws exception {
        jsonnode root = mapper.readtree(json);

        // 使用 jsonpointer 定位节点
        jsonpointer ptr = jsonpointer.compile("/store/book/0/author");
        jsonnode authornode = root.at(ptr);
        string author = authornode.astext();

        // 链式写法
        string title = root.at("/store/book/1/title").astext();
        double price = root.at("/store/bicycle/price").asdouble();
    }
}

jsonpointer 限制

  • 语法较简单,不支持通配符、过滤表达式
  • 无法一次获取多个值
  • 不支持数组切片

方式二:使用 jackson-jsonpath(第三方扩展)

<dependency>
    <groupid>com.jayway.jsonpath</groupid>
    <artifactid>json-path</artifactid>
    <version>2.9.0</version>
</dependency>
import com.jayway.jsonpath.configuration;
import com.jayway.jsonpath.jsonpath;
import com.jayway.jsonpath.spi.json.jacksonjsonnodejsonprovider;
import com.jayway.jsonpath.spi.mapper.jacksonmappingprovider;

public class jacksonjsonpathexample {

    // 配置使用 jackson
    private configuration configuration = configuration.builder()
        .jsonprovider(new jacksonjsonnodejsonprovider())
        .mappingprovider(new jacksonmappingprovider())
        .build();

    @test
    public void testjacksonjsonpath() {
        list<string> authors = jsonpath.using(configuration)
            .parse(json)
            .read("$.store.book[*].author");
    }
}

gson - 无原生 jsonpath

gson 本身不提供 jsonpath 支持,这是 gson 的一个局限。建议搭配 jayway jsonpath 使用。

<dependency>
    <groupid>com.google.code.gson</groupid>
    <artifactid>gson</artifactid>
    <version>2.11.0</version>
</dependency>

<dependency>
    <groupid>com.jayway.jsonpath</groupid>
    <artifactid>json-path</artifactid>
    <version>2.9.0</version>
</dependency>
import com.google.gson.gson;
import com.google.gson.jsonelement;
import com.jayway.jsonpath.jsonpath;

public class gsonjsonpathexample {

    private gson gson = new gson();
    private string json = "...";

    @test
    public void testgsonwithjsonpath() {
        // 使用 jsonpath 提取数据
        list<string> authors = jsonpath.parse(json)
            .read("$.store.book[*].author");

        // 将结果转回 gson 对象
        jsonelement element = gson.tojsontree(authors);
    }
}

三种方案对比

特性fastjsonjackson + jsonpointerjayway jsonpath
jsonpath 支持原生支持仅 jsonpointer完整支持
过滤表达式支持不支持支持
通配符支持不支持支持
性能优秀优秀良好
生态稳定性曾有安全漏洞最稳定社区活跃
spring boot 集成需手动配置默认集成需添加依赖

选型建议

  • 已有 fastjson 项目:直接使用 fastjson 的 jsonpath
  • 使用 jackson 的项目:简单场景用 jsonpointer,复杂场景引入 jayway jsonpath
  • 使用 gson 的项目:建议搭配 jayway jsonpath 使用
  • 新项目:推荐 jackson + jayway jsonpath 组合

总结

jsonpath 是处理 json 数据的利器,通过简洁的路径表达式实现复杂字段提取、条件过滤和动态查询。在 spring boot 中集成 jsonpath 可大幅简化代码、提升可读性,是处理复杂 json 结构和第三方 api 数据的一种可选技术方案。

以上就是springboot使用jsonpath实现高效处理json数据的详细内容,更多关于springboot处理json数据的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com