Featured resource
Tech Upskilling Playbook 2025
Tech Upskilling Playbook

Build future-ready tech teams and hit key business milestones with seven proven plays from industry leaders.

Learn more
  • Labs icon Lab
  • Core Tech
Labs

Guided: Spring Certified Professional - Developing REST Applications with Spring MVC

In this guided hands-on lab, you will design and implement RESTful web services using Spring MVC. You’ll create controller methods to handle HTTP GET, POST, PUT, and DELETE requests, and use RestTemplate to consume external REST services. By the end of this lab, you will be confident in building and invoking RESTful APIs using Spring MVC and Spring Boot.

Labs

Path Info

Level
Clock icon Advanced
Duration
Clock icon 1h 1m
Last updated
Clock icon Aug 18, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Introduction to RESTful Architecture with Spring MVC

    In this lab, you will build a RESTful service for a product inventory system at Globomantics. The service will support Create, Read, Update, and Delete (CRUD) operations and demonstrate how to consume external data using RestTemplate.

    You’ll explore how Spring MVC simplifies REST API development using annotation-driven configuration, and learn how to build robust, readable, and testable endpoints.


    What You Will Learn

    • The core principles of REST architecture
    • How Spring MVC enables RESTful services using annotations
    • How to define HTTP endpoints using @RestController, @RequestMapping, and method-specific annotations like @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping

    What is REST?

    REST (Representational State Transfer) is an architectural style for designing networked applications. RESTful services:

    • Are stateless — each request carries all necessary context
    • Operate on resources identified by URIs
    • Use standard HTTP methods: GET, POST, PUT, DELETE

    What is Spring MVC?

    Spring MVC is part of the Spring Framework that supports building web applications, including RESTful APIs. It follows the Model-View-Controller pattern and promotes clean, testable code using annotations.

    Spring MVC provides:

    • Request mapping to controller methods
    • Content negotiation (e.g., JSON, XML)
    • Automatic object serialization and deserialization
    • Annotation-based exception handling

    In the next step, you will explore the project structure and define the Product model class to represent your API’s primary resource.

  2. Challenge

    Understand Project Structure and Create Model

    In this step, you will get familiar with the Spring Boot project structure that has already been set up for you. You will also define the Product class that represents the data model for the REST API.

    Project Structure Overview

    The base Spring Boot project is already created and the source code is organized under the src/main/java/com/globomantics/inventory/ directory. This is where your application files reside.

    The structure looks like this for inventory-service :

    src/
    └── main/
        └── java/
            └── com/globomantics/inventory/
                ├── InventoryApplication.java
                ├── controller/
                │   └── ProductController.java
                │   └── InventoryMonitorController.java
                ├── model/
                │   └── Product.java
                ├── service/
                │   └── ProductService.java
                └── exception/
                    ├── GlobalExceptionHandler.java
                    └── ProductNotFoundException.java
    
    • InventoryApplication.java is the main Spring Boot entry point.
    • The controller/ package contains ProductController.java, which defines the REST API endpoints.
    • InventoryMonitorController.java consumes internal REST endpoints using RestTemplate. It adds monitoring capability to identify products with low stock (quantity < 10)
    • The model/ package contains Product.java, the domain model class.
    • The service/ package contains ProductService.java, which holds business logic for managing products.
    • The exception/ package includes:
      • ProductNotFoundException.java to represent missing resources.
      • GlobalExceptionHandler.java to handle exceptions consistently across the application.

    Now that you're familiar with the overall project structure, it's time to start implementing the core parts of the application.

    The first component you will work on is the Product model, which represents the data structure for each product in the inventory system. This class will later be used to exchange data between the controller and service layers and eventually returned as JSON from your REST endpoints. In this step, you explored the structure of the Spring Boot project and updated the Product model. In the next step, you will implement the REST controller to expose endpoints for managing products.

  3. Challenge

    Create REST Controller for Product Resource

    In this step, you will complete the partially implemented ProductController class. This controller defines REST endpoints that allow clients to create, retrieve, update, and delete products.

    File is located in the package com.globomantics.inventory.controller.

    Your task is to complete specific methods that handle different HTTP operations.

    --- ### What You Will Do

    In this step, you will work with Spring MVC annotations to expose RESTful endpoints for product management. You will complete a partially implemented controller by adding the appropriate annotations and logic for handling different HTTP methods.

    You will use the following annotations:

    | Annotation | Purpose | |--------------------|-------------------------------------------------------------------------| | @RestController | Declares the class as a REST controller. Automatically serializes return values into JSON | | @RequestMapping | Maps a URI path to a controller class or method | | @GetMapping | Maps HTTP GET requests to a method (e.g., retrieve products) | | @PostMapping | Maps HTTP POST requests to a method (e.g., create a product) | | @PutMapping | Maps HTTP PUT requests to a method (e.g., update a product) | | @DeleteMapping | Maps HTTP DELETE requests to a method (e.g., delete a product) |

    Now you'll begin by annotating the class itself. You’ve now exposed an endpoint to retrieve all products. Next, you’ll learn how to handle requests for a specific product using dynamic URL values.

    Before jumping into the next task, you'll explore how to extract values like path variables, query parameters, and request bodies using Spring MVC method parameter annotations.

    Understanding Method Parameter Annotations in Spring MVC

    When building RESTful APIs with Spring MVC, controller methods often need to access different parts of the incoming HTTP request like URL path values, query parameters, or the request body. Spring provides a set of annotations to extract these values and bind them directly to method parameters:

    | Annotation | Used For | Example Usage | | ---------------- | -------------------------------------------------- | ------------------------------------------------------------ | | @PathVariable | Extracting dynamic values from the URL path | /products/101@PathVariable Long id | | @RequestParam | Reading query parameters from the URL | /products?category=books@RequestParam String category | | @RequestBody | Mapping the JSON payload of a request to an object | POST with JSON body → @RequestBody Product product | | @RequestHeader | Reading values from HTTP headers | @RequestHeader("Authorization") String token |


    @PathVariable

    Use this to bind a value embedded in the URI path. For example:

    @GetMapping("/products/{id}")
    public Product getProduct(@PathVariable Long id) {
        // id will contain the value from the URL path
    }
    

    @RequestParam

    Use this to bind a query parameter from the URL. Example:

    @GetMapping("/products")
    public List<Product> getByCategory(@RequestParam String category) {
        // Binds the value of ?category=XYZ
    }
    

    @RequestBody

    Use this to bind the JSON request body to a Java object. Example:

    @PostMapping("/products")
    public Product createProduct(@RequestBody Product product) {
        // product object is populated from the JSON request body
    }
    

    These annotations make it easy to handle HTTP input in a clean and declarative way.

    Now that you understand how to extract values from the request, you'll apply that knowledge to handle a request for a specific product by its ID. In this step, you annotated a Java class to function as a REST controller using Spring MVC. You exposed endpoints for CRUD operations by completing methods with @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping.

    In the next step, you will enhance these endpoints to return proper HTTP status codes using ResponseEntity.

  4. Challenge

    Use ResponseEntity for Custom Responses

    In this step, you will enhance the existing controller methods that currently return plain Java objects. Your goal is to make them RESTful by wrapping responses in ResponseEntity and returning appropriate HTTP status codes based on the outcome of each operation.

    --- ### HTTP Status Codes

    HTTP status codes are standardized responses provided by web servers to indicate the result of a client's request. They convey information about the success or failure of the request, as well as additional context about the response.

    Categories of HTTP Status Codes

    HTTP status codes are categorized into five main classes:

    | Status Code | Description | | -------- | -------- | | 1xx Informational | Indicate that the request has been received and the process is continuing. | | 2xx Success | Indicate that the request was successful and the server has fulfilled it. | | 3xx Redirection | Indicate that further action must be taken by the client to complete the request. | | 4xx Client Error | Indicate that there was an issue with the client's request, such as invalid input or authentication failure. | | 5xx Server Error | Indicate that there was an issue on the server side while processing the request. |

    Examples of common scenarios and their corresponding HTTP status codes:

    200 OK: Successful response to a GET request.

    201 Created: Successful creation of a new resource in response to a POST request.

    400 Bad Request: Client's request cannot be fulfilled due to invalid input.

    401 Unauthorized: Client lacks proper authentication credentials.

    404 Not Found: The requested resource could not be found.

    500 Internal Server Error: The server encountered an unexpected condition.


    Common HTTP Status Codes and Their Spring Representations

    | HTTP Status Code | Meaning | Spring Representation | | ---------------- | ---------------------------- | ---------------------------------- | | 200 | OK (Success) | HttpStatus.OK | | 201 | Created (Resource created) | HttpStatus.CREATED | | 404 | Not Found (Resource missing) | HttpStatus.NOT_FOUND | | 500 | Internal Server Error | HttpStatus.INTERNAL_SERVER_ERROR | In Spring MVC, you can use the ResponseEntity class to build a complete HTTP response, including the status code and response body.

    There are two common ways to specify the HTTP status:


    Using ResponseEntity.status(int).body(...)

    You can directly pass a numeric status code (like 201 for "Created") using ResponseEntity.status():

    return ResponseEntity.status(201).body(product);
    

    This is concise and easy to read when you're working with well-known status codes.


    Using ResponseEntity with HttpStatus Enum

    Spring also provides the HttpStatus enum for named constants that improve readability:

    return new ResponseEntity<>(product, HttpStatus.CREATED);
    

    This is useful when you want to be explicit about the meaning of the status code in your codebase.


    Both styles are valid. For this lab, you'll use the latter new ResponseEntity<>(..., HttpStatus.XXX) style to reinforce understanding of HTTP semantics.

    What You Will Do

    Each method is already implemented with default return types i.e Product. You will:

    • Update each return type to ResponseEntity<?>
    • Add conditional logic to return proper status codes like 200 OK, 404 Not Found, or 204 No Content

    All required changes should be made directly in the existing controller methods, marked with comments like // Task 4.x.

    --- In this step, you used ResponseEntity to return clearer, structured HTTP responses. This also improves readability and maintainability.

    In the next step, you will implement global exception handling using @ControllerAdvice to manage errors consistently across your application.

  5. Challenge

    Global Error Handling

    In this step, you will implement global exception handling using Spring MVC's @ControllerAdvice. Instead of returning raw stack traces or default error pages, your application will now return clean, consistent error messages in the HTTP response.

    You will handle custom exceptions like ProductNotFoundException and return meaningful HTTP status codes such as 404 Not Found.


    Why Handle Errors Globally?

    Imagine a scenario where a client tries to fetch a product that does not exist using: GET /products/99

    Without proper error handling, Spring will return a default error page or a 500 Internal Server Error, which doesn't help the client understand what went wrong.

    Instead, by throwing a custom exception like ProductNotFoundException and handling it globally using @ExceptionHandler, you can return a meaningful message and status:

    {
    "message": "Product with ID 99 not found"
    }
    HTTP Status: 404 Not Found
    

    Review the custom exception class ProductNotFoundException defined in package com.globomantics.exception.

    In the next set of tasks, you will:

    • throw the ProductNotFoundException from service.
    • Create a global exception handler using @ControllerAdvice
    • Handle the ProductNotFoundException and return a 404 Not Found response In this step, you added global exception handling to your Spring MVC application using @ControllerAdvice and @ExceptionHandler. This makes your API responses cleaner and more informative by returning structured error messages instead of raw stack traces.

    In the next step, you will test the API using curl to verify that all endpoints and error handling work as expected.

  6. Challenge

    Test API using curl

    In this step, you will verify that your REST API behaves as expected by issuing requests from the terminal using curl. You will test successful scenarios and error conditions to confirm that all controller methods and HTTP responses are working properly.

    In the First Terminal window, use below command to start the Spring boot application.

    cd inventory-service
    
    mvn spring-boot:run
    

    You should see a message like the following in the Terminal, indicating a successful startup:

    Started InventoryApplication in 1.632 seconds (process running for 2.437)
    

    info> Ensure your Spring Boot application is running locally successfully before attempting the task.

    Note: You can use CTRL+C to stop the application. ### What You Will Do

    You will use curl to test the following three key operations:

    • Create a new product
    • Retrieve the product by ID
    • Delete the product

    Each test will validate the appropriate HTTP method (POST, GET, DELETE) and confirm status codes like 200 OK, 204 No Content, and 404 Not Found.

    You will use the Second Terminal window to test the APIs using curl. You will receive a response managed by the GlobalExceptionHandler.

    Output:

    Resource not found
    HTTP Status : 404
    ``` In this step, you’ve successfully verified your API endpoints using `curl`. These tests confirm that your implementation returns the correct data, responds with appropriate HTTP status codes, and handles errors gracefully.
    
    In the next step, you’ll learn how to consume this API from another service.
    
  7. Challenge

    Consume API with RestTemplate

    In this step, you will use another controller inside the same Spring Boot application to simulate an internal service communicating with the existing Product API. This controller will use Spring’s RestTemplate to call the /products endpoint and identify products that are low stock having quantity less than 10.

    This exercise demonstrates how one part of an application can act as a client to another part, using RestTemplate to communicate over HTTP.


    What You Will Do

    • Define a RestTemplate bean
    • Update code in the new controller: InventoryMonitorController
    • Use RestTemplate to call GET /products
    • Test the endpoint ### What is RestTemplate

    RestTemplate is a Spring-provided HTTP client used for making synchronous REST API calls. It enables one component of your application to communicate with another using standard HTTP methods such as GET, POST, PUT, and DELETE.

    It simplifies:

    • Sending requests to external or internal endpoints
    • Automatically converting responses into Java objects
    • Handling HTTP status codes and headers with ResponseEntity

    Common RestTemplate Methods

    | Method | Purpose | Returns | |---------------------|------------------------------------|----------------------------------| | getForObject | Perform a GET request | Response body (object) | | getForEntity | Perform GET, get full response | ResponseEntity (status + body)| | postForObject | POST with request body | Created object | | postForEntity | POST and get full response | ResponseEntity |


    Example

    ResponseEntity<Product[]> response =
          restTemplate.getForEntity(
          "http://localhost:8080/products", 
          Product[].class);
    
    Product[] products = response.getBody();
    

    Next you'll define the RestTemplate bean and use the getForEntity to call the Product API. info> You need to restart the application for the recent changes to be applicable.

    If the application is already running, press CTRL+C in the first Terminal to stop it. Then, ensure you're in the inventory-service folder and run the following command to restart the Spring Boot application:

    mvn spring-boot:run
    

    You will use the second Terminal window to test the API endpoint.

    Next, test the /monitor/low-stock endpoint to ensure it returns the expected low-stock products. In this step, you created a monitoring controller that consumes another REST endpoint using RestTemplate.

    You also tested the endpoint using curl to confirm the integration works as expected.

    In the next and final step, you’ll review everything you’ve built and explore ways to extend your Spring MVC RESTful service further.

  8. Challenge

    Conclusion and Next Steps

    Congratulations! You have successfully completed the lab on developing RESTful applications using Spring MVC.

    Throughout this hands-on experience, you:

    • Learned REST principles and how Spring MVC supports them using annotations
    • Built a REST controller to expose product-related endpoints
    • Enhanced your controller methods with ResponseEntity for status management
    • Implemented global exception handling with @ControllerAdvice
    • Verified your API with real HTTP requests using curl
    • Demonstrated API consumption using RestTemplate

    Next Steps

    Here are some ideas for extending your learning:

    • Connect the API to a database using Spring Data JPA
    • Add validation logic using @Valid and @NotNull annotations
    • Secure your endpoints using Spring Security
    • Use WebClient instead of RestTemplate for reactive applications
    • Write integration tests using MockMvc

    Thank you for completing the lab!

    Your understanding of Spring MVC’s core capabilities in REST development now puts you in a strong position to build and scale real-world applications.

Amar Sonwani is a software architect with more than twelve years of experience. He has worked extensively in the financial industry and has expertise in building scalable applications.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.