Jayway JsonPath is an opensource implementation of JsonPath for Java. We can use JsonPath to query and traverse through JSON data.

In this post, we will learn about the basic usage of JasonPath Maven library and how to use it in our spring application.

We will create a simple spring boot application and a few REST endpoints to retrieve the JSON data from backend service.

Create a spring boot application

Create a spring boot application with spring-boot-starter-web, lombok(to reduce boilerplate code) and json-path dependencies.

The complete pom.xml file is given below.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.3.BUILD-SNAPSHOT</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.asb.example</groupId>
	<artifactId>spring-jsonpath-example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-jsonpath-example</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.jayway.jsonpath</groupId>
			<artifactId>json-path</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Create DTO classes

We will create a few simple DTO classes and relate them to form a nested JSON structure.

Create java classes called School.java, Student.java and Grade.java

School.java

package com.asb.example.dto;

import java.util.ArrayList;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class School {
	private String name;
	List<Student> students = new ArrayList<>();
}

Student.java

package com.asb.example.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Student {
	private String firstName;
	private String lastName;
	private Grade grade;
}

Grade.java

package com.asb.example.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Grade {
	private String name;
}

Create Service layer

Create a spring service class to create and return objects of the above created DTO classes.

Create a class called JsonUtil.java as shown below. This class just creates the Objects and returns back to service class.

JsonUtil.java

package com.asb.example.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.asb.example.dto.Grade;
import com.asb.example.dto.School;
import com.asb.example.dto.Student;

@Component
public class JsonUtil {

	public School getSchoolDetails() {
		
		School school = new School();
		school.setName("My School");
		
		List<Student> students = new ArrayList<>();
		Student student1 = new Student();
		student1.setFirstName("Arun");
		student1.setLastName("SB");

		Grade grade1 = new Grade();
		grade1.setName("XI");
		student1.setGrade(grade1);
		
		Student student2 = new Student();
		student2.setFirstName("John");
		student2.setLastName("Taylor");

		Grade grade2 = new Grade();
		grade2.setName("X");
		student2.setGrade(grade2);
		
		Student student3 = new Student();
		student3.setFirstName("Malcom");
		student3.setLastName("Jr");

		Grade grade3 = new Grade();
		grade3.setName("VII");
		student3.setGrade(grade3);
		
		students.add(student1);
		students.add(student2);
		students.add(student3);
		
		school.setStudents(students);
		
		return school;
	}
}

Create a service class with name SchoolService.java as shown below.

SchoolService.java

package com.asb.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class SchoolService {

	@Autowired
	private JsonUtil jsonUtil;

	private static final ObjectMapper om = new ObjectMapper();

	public String getDetails() throws JsonProcessingException {

		return om.writeValueAsString(jsonUtil.getSchoolDetails());
	}
}

Create a controller layer

The actual operation of JsonPath will be implemented here. We will create different end points to get different json details by using JsonPath functions and queries.

SchoolController.java

package com.asb.example.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.asb.example.dto.Student;
import com.asb.example.service.SchoolService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;

@RestController
public class SchoolController {

	@Autowired
	private SchoolService schoolService;

	private static final ObjectMapper om = new ObjectMapper();

	@GetMapping("/get-school-details")
	public ResponseEntity<String> getSchoolDetails() throws JsonProcessingException {
		return new ResponseEntity<>(schoolService.getDetails(), HttpStatus.OK);
	}

	@GetMapping("/get-students")
	public ResponseEntity<String> getStudentDetails() throws JsonProcessingException {
		String json = schoolService.getDetails();
		Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
		List<Student> students = JsonPath.read(document, "$.students");
		return new ResponseEntity<>(om.writeValueAsString(students), HttpStatus.OK);
	}

	@GetMapping("/get-student-names")
	public ResponseEntity<String> getStudentNames() throws JsonProcessingException {
		String json = schoolService.getDetails();
		Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
		List<String> students = JsonPath.read(document, "$.students[*].firstName");
		return new ResponseEntity<>(om.writeValueAsString(students), HttpStatus.OK);
	}

	@GetMapping("/student-count")
	public ResponseEntity<Integer> getStudentCount() throws JsonProcessingException {
		String json = schoolService.getDetails();
		Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
		Integer count = JsonPath.read(document, "$.students.length()");
		return new ResponseEntity<>(count, HttpStatus.OK);
	}

	@GetMapping("/student/{firstName}")
	public ResponseEntity<List<Student>> getStudentCount(@PathVariable(value="firstName") String firstName) throws JsonProcessingException {
		String json = schoolService.getDetails();
		Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
		List<Student> students = JsonPath.read(document, "$..[?(@.firstName=='" + firstName + "')]");
		return new ResponseEntity<>(students, HttpStatus.OK);
	}
}

The above controller has following endpoints where different JsonPath features have been used.

  • /get-school-details: Returns complete JSON details.
  • /get-students: Returns list of available student JSON details.
  • /get-student-names: Returns array of student First name details.
  • /student-count: Returns count of students.
  • /student/{firstName}: Returns list of student, matched firstName field of Student JSON representation.

There are many other features available in JsonPath, and are explained in documentation.

Run the application

Start the spring boot application and test the end points.

/get-school-details

jsonpath example

/get-students

jsonpath example spring

/get-student-names

jsonpath example spring

/student-count

jsonpath example spring

/student/{firstName}

jsonpath example spring

Conclusion

In this post, we learned how to use JayWay JsonPath Maven library in spring application development. This opensource library is very helpful while writing the JUnit test cases, where we can evaluate response JSON object retrieved from REST end points.

Sample code is available on GitHub. Happy coding! 🙂

You may also interested in