In Spring MVC or Spring Boot, you handle HTTP requests by creating controller classes. A controller receives a request, runs application logic, and returns either:
- a view name for server-rendered pages, or
- data such as JSON for REST APIs.
1. Basic Spring MVC Controller
Use @Controller when you want to return views such as JSP, Thymeleaf, or other templates.
package com.example.web;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("message", "Welcome to Spring MVC!");
return "home";
}
}
In this example:
@Controllermarks the class as a Spring MVC controller.@GetMapping("/")handles HTTPGET /.Modelpasses data to the view."home"is the logical view name.
If you use Thymeleaf, Spring would typically look for:
src/main/resources/templates/home.html
2. REST Controller Returning JSON
Use @RestController when you want to build REST APIs.
package com.example.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingRestController {
@GetMapping("/api/greeting")
public Greeting greeting() {
return new Greeting("Hello from Spring!");
}
public record Greeting(String message) {
}
}
Calling:
GET /api/greeting
returns JSON like:
{
"message": "Hello from Spring!"
}
@RestController is a shortcut for:
@Controller
@ResponseBody
So every method returns the response body directly instead of a view name.
3. Handling Different HTTP Methods
Spring provides convenient annotations for common HTTP methods.
package com.example.web;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/users")
public String getUsers() {
return "Get all users";
}
@PostMapping("/users")
public String createUser() {
return "Create a new user";
}
@PutMapping("/users/1")
public String replaceUser() {
return "Replace user";
}
@PatchMapping("/users/1")
public String updateUser() {
return "Update part of user";
}
@DeleteMapping("/users/1")
public String deleteUser() {
return "Delete user";
}
}
Common mappings include:
| Annotation | HTTP Method |
|---|---|
@GetMapping |
GET |
@PostMapping |
POST |
@PutMapping |
PUT |
@PatchMapping |
PATCH |
@DeleteMapping |
DELETE |
4. Reading Path Variables
Use @PathVariable to read values from the URL path.
package com.example.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
@GetMapping("/products/{id}")
public String getProduct(@PathVariable Long id) {
return "Product ID: " + id;
}
}
Request:
GET /products/10
Response:
Product ID: 10
5. Reading Query Parameters
Use @RequestParam to read query string parameters.
package com.example.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SearchController {
@GetMapping("/search")
public String search(
@RequestParam String keyword,
@RequestParam(defaultValue = "1") int page
) {
return "Searching for: " + keyword + ", page: " + page;
}
}
Request:
GET /search?keyword=spring&page=2
Response:
Searching for: spring, page: 2
6. Reading Request Body JSON
Use @RequestBody to bind JSON request data to a Java object.
package com.example.web;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
public record CreateUserRequest(String name, String email) {
}
@RestController
public class UserApiController {
@PostMapping("/api/users")
public String createUser(@RequestBody CreateUserRequest request) {
return "Created user: " + request.name() + " with email: " + request.email();
}
}
Request:
POST /api/users
Content-Type: application/json
{
"name": "Alice",
"email": "[email protected]"
}
7. Returning Proper HTTP Status Codes
Use ResponseEntity when you need control over the response status, headers, or body.
package com.example.web;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@PostMapping("/orders")
public ResponseEntity<String> createOrder() {
return ResponseEntity
.status(HttpStatus.CREATED)
.body("Order created");
}
}
This returns:
HTTP/1.1 201 Created
8. Handling Form Submissions
For traditional web applications, a controller can handle form submissions with @PostMapping.
package com.example.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class ContactController {
@PostMapping("/contact")
public String submitContactForm(
@RequestParam String name,
@RequestParam String message
) {
System.out.println("Name: " + name);
System.out.println("Message: " + message);
return "redirect:/contact-success";
}
}
The redirect prevents duplicate form submissions if the user refreshes the page.
9. Using a Service from a Controller
Controllers should usually be thin. Put business logic in a service class.
package com.example.web;
import com.example.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/api/users/count")
public int countUsers() {
return userService.countUsers();
}
}
package com.example.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public int countUsers() {
return 5;
}
}
This keeps the controller focused on HTTP request/response handling.
10. Simple Exception Handling
You can handle exceptions globally using @ControllerAdvice.
package com.example.web;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleIllegalArgumentException(IllegalArgumentException ex) {
return new ErrorResponse(ex.getMessage());
}
public record ErrorResponse(String message) {
}
}
Now if a controller throws:
throw new IllegalArgumentException("Invalid request");
Spring returns a 400 Bad Request response.
Quick Summary
Use these annotations to handle HTTP requests in Spring:
| Annotation | Purpose |
|---|---|
@Controller |
Web controller returning views |
@RestController |
REST controller returning response bodies |
@GetMapping |
Handle GET requests |
@PostMapping |
Handle POST requests |
@PutMapping |
Handle PUT requests |
@PatchMapping |
Handle PATCH requests |
@DeleteMapping |
Handle DELETE requests |
@PathVariable |
Read values from the URL path |
@RequestParam |
Read query parameters or form fields |
@RequestBody |
Read JSON/XML request body |
ResponseEntity |
Customize status, headers, and body |
@ControllerAdvice |
Centralized exception handling |
In short:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, Spring!";
}
}
That is the simplest form of handling an HTTP request with a Spring controller.
