- Lab
- Core Tech

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.

Path Info
Table of Contents
-
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. -
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 containsProductController.java
, which defines the REST API endpoints. InventoryMonitorController.java
consumes internal REST endpoints usingRestTemplate
. It adds monitoring capability to identify products with low stock (quantity < 10)- The
model/
package containsProduct.java
, the domain model class. - The
service/
package containsProductService.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 theProduct
model. In the next step, you will implement the REST controller to expose endpoints for managing products. -
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
. -
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") usingResponseEntity.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, or204
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. - Update each return type to
-
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 as404 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 packagecom.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 a404 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. - throw the
-
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 DoYou 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 like200 OK
,204 No Content
, and404 Not Found
.You will use the Second Terminal window to test the APIs using
curl
. You will receive a response managed by theGlobalExceptionHandler
.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.
-
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 thegetForEntity
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 theinventory-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 usingRestTemplate
.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.
- Define a
-
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 ofRestTemplate
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.
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.