[JAVA] Json Path

When XML has XPath, Json also has JsonPath. For Java, you can use libraries like:

  • Jackson: A powerful library for JSON parsing and serialization.
  • JsonPath: A library specifically for querying JSON documents with JSONPath syntax.

In this blog, I will show an example of interacting with JSON Path by using JSONPath 

Using JSONPath

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.8.0</version>
</dependency>
  • Key Features of JSONPath
AnotationDescription
$represents the root of the JSON document.
. or []is used for accessing child elements.
*is a wildcard that matches any element.
[?()]is used for filtering elements.
  • Example
import com.jayway.jsonpath.JsonPath;

public class JsonPathExample {
    public static void main(String[] args) {
        String json = "{ \"store\": { \"book\": [ " +
                      "{ \"category\": \"fiction\", \"title\": \"A\", \"price\": 10 }, " +
                      "{ \"category\": \"non-fiction\", \"title\": \"B\", \"price\": 15 } ] } }";

        // Query JSONPath
        String title = JsonPath.read(json, "$.store.book[0].title");
        System.out.println("First book title: " + title);

        Double price = JsonPath.read(json, "$.store.book[1].price");
        System.out.println("Second book price: " + price);
    }
}

More Complex Queries

  • Extract all book titles:
List<String> titles = JsonPath.read(json, "$.store.book[*].title");
  • Filter books with price greater than 10:
List<Map<String, Object>> expensiveBooks = JsonPath.read(json, "$.store.book[?(@.price > 10)]");

Using JSONPath with Jackson

While Jackson does not directly support JSONPath, you can combine it with the JSONPath library to extract data using JSONPath. Here’s an example:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.JsonPath;

public class JsonPathWithJackson {
    public static void main(String[] args) throws Exception {
        String json = "{ \"store\": { \"book\": [ " +
                      "{ \"category\": \"fiction\", \"title\": \"A\", \"price\": 10 }, " +
                      "{ \"category\": \"non-fiction\", \"title\": \"B\", \"price\": 15 } ] } }";

        // Parse JSON with Jackson ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(json);

        // Use JsonPath to query JSON
        String firstBookTitle = JsonPath.read(jsonNode.toString(), "$.store.book[0].title");
        System.out.println("First book title: " + firstBookTitle);

        double secondBookPrice = JsonPath.read(jsonNode.toString(), "$.store.book[1].price");
        System.out.println("Second book price: " + secondBookPrice);
    }
}

using JSONPath in a Spring Boot

you can integrate the JsonPath library with your project. Here’s a step-by-step guide

  • Create Spring Boot Project and Add Maven JSONPath Dependency in your pom
  • Spring Boot Project Structure. this project have 1 endpoint /api/jsonpath/extract and 2 input
    - Body: json data
    - Query Parameter: Your JSONPath
src/main/java/com/example/jsonpathdemo
├── controller
│   └── JsonPathController.java
├── service
│   └── JsonPathService.java
└── JsonPathDemoApplication.java
  • JsonPathService.java
package com.example.jsonpathdemo.service;

import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class JsonPathService {

    public String getValueFromJson(String json, String jsonPath) {
        try {
            // Use JsonPath to extract data
            return JsonPath.read(json, jsonPath);
        } catch (PathNotFoundException e) {
            return "Invalid JSONPath: " + jsonPath;
        } catch (Exception e) {
            return "Error processing JSON: " + e.getMessage();
        }
    }
}
  • JsonPathController.java
package com.example.jsonpathdemo.controller;

import com.example.jsonpathdemo.service.JsonPathService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/jsonpath")
public class JsonPathController {

    private final JsonPathService jsonPathService;

    public JsonPathController(JsonPathService jsonPathService) {
        this.jsonPathService = jsonPathService;
    }

    @PostMapping("/extract")
    public String extractValue(@RequestBody String json, @RequestParam String jsonPath) {
        // Call the service to process JSONPath
        return jsonPathService.getValueFromJson(json, jsonPath);
    }
}
  • Run the application with mvn spring-boot:run

In testing step, you can use a tool like Postman or cURL to send a POST request to the endpoint. with sample request

  • URLhttp://localhost:8080/api/jsonpath/extract
  • MethodPOST
  • HeadersContent-Type: application/json
  • Body:
{
  "store": {
    "book": [
      { "category": "fiction", "title": "A", "price": 10 },
      { "category": "non-fiction", "title": "B", "price": 15 }
    ]
  }
}
  • Query ParameterjsonPath=$.store.book[0].title

The result should be A

You can customize the jsonPath parameter to perform more complex queries such as

  • Get all book titles: jsonPath=$.store.book[*].title
  • Get books with price greater than 10: jsonPath=$.store.book[?(@.price > 10)]
  • Get the first book category: jsonPath=$.store.book[0].category

จบไปและกับ Blog ที่ดองกว่า 4 ปี 55


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.