• Spring Boot Rest JSON Tutorial

    In our previous post, we learned how to create a REST application in Java using JAX-RS. In this tutorial, we will be creating a Spring Boot Rest JSON Application and learn the different annotations in Spring and how it works.

    We will use the same example in our previous post wherein there is a Student System that accepts web services calls. First, we’ll create a Spring Boot Application. If you’re new to Spring Boot, you might want to read first our article on How To Get Started in Spring Boot.

    In your pom.xml, add the necessary dependencies:

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.5.RELEASE</version>
            <relativePath/> 
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-json</artifactId>
            </dependency>
        </dependencies>
    

    Then, we will create a Rest Controller that handles web services requests.

    @RestController
    @RequestMapping(value = "/student", produces = MediaType.APPLICATION_JSON_VALUE)
    public class StudentController {
        //methods here
    }
    

    @RestController – means that the controller can handle Rest Webservices. It’s also equivalent to @Controller annotation plus @ResponseBody annotation.

    @RequestMapping(value = “/student”, produces = MediaType.APPLICATION_JSON_VALUE) – we have created a parent request mapping annotation with value “/student” which means that this controller will handle all request that starts with “/student” in URL. The produces = MediaType.APPLICATION_JSON_VALUE means that the response that will be produced will be converted into JSON format.

    Using GET Method

        @RequestMapping(method = RequestMethod.GET, value = "/info/{id}")
        public ResponseEntity<Student> getStudent(@PathVariable("id") long studentId) {
            Student student = studentService.getStudent(studentId);
            if (student != null) {
                return ResponseEntity.ok(student);
            }
            return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);
        }
    

    The request mapping has been set to only accept GET requests. The URL mapping should starts with “/student/info/” plus any id. The PathVariable annotation automatically maps the {id} to the studentId variable. We also use ResponseEntity object as our return type which can hold both the status code and response body. This makes it easier to return specific types of status codes in the response.

     

    Using PUT Method

        @RequestMapping(method = RequestMethod.PUT, value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<Long> addStudent(@RequestBody Student student) {
            long id = studentService.addStudent(student);
            return ResponseEntity.ok(id);
        }
    

    Here, we specify that we only consume a JSON formatted request body. We also add the annotation @RequestBody which automatically maps a JSON request to Student object.

     

    Using POST Method

        @RequestMapping(method = RequestMethod.POST, value = "/set/subjects/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<Student> addSubjectsToStudent(@PathVariable("id") long studentId,
                                                            @RequestParam("subjects") String subjects) {
            Student student = studentService.setSubjects(studentId, subjects.split(","));
            return ResponseEntity.ok(student);
        }
    

    The above example is almost similar to the GET method aside from that it only accept requests that are in the POST method. We can also specify the RequestParam required as false and set its default value. For example:

        @RequestMapping(method = RequestMethod.POST, value = "/set/subjects/year/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<Student> addSubjectsAndYear(@PathVariable("id") long studentId,
                                                          @RequestParam("subjects") String subjects,
                                                          @RequestParam(required = false, name = "year", defaultValue = "0") int year) {
            Student student = studentService.setSubjectsAndYear(studentId, year, subjects.split(","));
            return ResponseEntity.ok(student);
        }
    

    We have set the parameter “year” as required false and set its default value to “0”. Lastly, instead of RequestParam, we can use RequestBody as if we are sending JSON formatted parameter values. For example, if we want the below JSON formatted values to be sent and consumed by our web services, we need to create a java class that can hold those values:

    Sample Request:
    {
    	"studentId": "1",
    	"subjects" : [
    			"MATH",
    			"ENGLISH"
    		]
    }
    
    SubjectRequest.java
    public class SubjectRequest {
    
        private int studentId;
        private List<String> subjects;
    
        public int getStudentId() {
            return studentId;
        }
    
        public void setStudentId(int studentId) {
            this.studentId = studentId;
        }
    
        public List<String> getSubjects() {
            return subjects;
        }
    
        public void setSubjects(List<String> subjects) {
            this.subjects = subjects;
        }
    }
    

    And in our controller, we need to create a method for our POST that will have to accept a RequestBody.

        @RequestMapping(method = RequestMethod.POST, value = "/set/subjects/", consumes = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<Student> addSubjects(@RequestBody SubjectRequest subjectRequest) {
            Student student = studentService.setSubjects(subjectRequest.getStudentId(), subjectRequest.getSubjects().toArray(new String[0]));
            return ResponseEntity.ok(student);
        }
    

     

    Using DELETE Method

    The delete request method is most commonly used to delete a record in the system. It looks like a GET method but users will not mistakenly delete a record by just visiting the URL.

        @RequestMapping(method = RequestMethod.DELETE, value = "/delete/{id}")
        public ResponseEntity<Boolean> deleteStudent(@PathVariable("id") long studentId) {
            boolean isSuccess = studentService.deleteStudent(studentId);
            if (isSuccess) {
                return ResponseEntity.ok(isSuccess);
            }
            return ResponseEntity.badRequest().body(false);
        }
    

     

    Testing the Spring Boot REST JSON Web Service

    We use POSTMAN to test our web service. Below are the sample request and response:

    GET

    Request:
    {
        "id": 1,
        "firstName": "John",
        "lastName": "Dell",
        "birthDate": "1995-04-01",
        "yearInSchool": 2,
        "currentSubjects": [
            "SCIENCE"
        ]
    }
    

    PUT

    Request:
    URL: http://localhost:8080/student/add
    Body:
    {
        "id": 1,
        "firstName": "John",
        "lastName": "Dell",
        "yearInSchool": 2,
        "currentSubjects": [
            "CHEMISTRY",
            "MATH",
            "ENGLISH"
        ]
    }
    
    Response:
    222
    //returns the id of the student generated
    

    POST

    Simple POST Request:

    Request:
    URL: http://localhost:8080/student/set/subjects/1?subjects=ENGLISH,MATH
    
    Response:
    {
        "id": 1,
        "firstName": "John",
        "lastName": "Dell",
        "birthDate": "1995-04-01",
        "yearInSchool": 2,
        "currentSubjects": [
            "MATH",
            "SCIENCE",
            "ENGLISH"
        ]
    }
    

    POST Request with Request Parameter set as false:

    Request:
    URL: http://localhost:8080/student/set/subjects/year/1?subjects=ENGLISH,MATH
    
    Response:
    {
        "id": 1,
        "firstName": "John",
        "lastName": "Dell",
        "birthDate": "1995-04-01",
        "yearInSchool": 0,
        "currentSubjects": [
            "MATH",
            "SCIENCE",
            "ENGLISH"
        ]
    }
    

    Post Request with Request Body:

    Request:
    URL: http://localhost:8080/student/set/subjects/
    {
    	"studentId": "1",
    	"subjects" : [
    			"MATH",
    			"ENGLISH"
    		]
    }
    
    Response:
    {
        "id": 1,
        "firstName": "John",
        "lastName": "Dell",
        "birthDate": "1995-04-01",
        "yearInSchool": 2,
        "currentSubjects": [
            "MATH",
            "SCIENCE",
            "ENGLISH"
        ]
    }
    

    DELETE

    Request:
    URL: http://localhost:8080/student/delete/1
    
    Response:
    true
    

    You can download the source code using this link.

    Related Post