Handling not found exceptions helps your app respond clearly when something is missing. It avoids crashes and tells users what went wrong.
Handling not found exceptions in Spring Boot
import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(HttpStatus.NOT_FOUND) public class ResourceNotFoundException extends RuntimeException { public ResourceNotFoundException(String message) { super(message); } }
Use @ResponseStatus(HttpStatus.NOT_FOUND) to set the HTTP status code to 404.
Extend RuntimeException to create a custom unchecked exception.
public class UserNotFoundException extends RuntimeException { public UserNotFoundException(String message) { super(message); } }
@ResponseStatus(HttpStatus.NOT_FOUND) public class UserNotFoundException extends RuntimeException { public UserNotFoundException(String message) { super(message); } }
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<String> handleNotFound(ResourceNotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } }
This Spring Boot app has a simple user map. When you ask for a user by ID, it returns the name if found. If not, it throws UserNotFoundException. The exception handler sends a 404 status with a clear message.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @SpringBootApplication @RestController public class DemoApplication { private Map<Integer, String> users = new ConcurrentHashMap<>(); public DemoApplication() { users.put(1, "Alice"); users.put(2, "Bob"); } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @GetMapping("/users/{id}") public String getUser(@PathVariable int id) { String user = users.get(id); if (user == null) { throw new UserNotFoundException("User with id " + id + " not found."); } return user; } @ResponseStatus(HttpStatus.NOT_FOUND) static class UserNotFoundException extends RuntimeException { public UserNotFoundException(String message) { super(message); } } @ExceptionHandler(UserNotFoundException.class) public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } }
Always provide a clear message in your exception to help users and developers understand the problem.
Use @ControllerAdvice for global exception handling across all controllers.
Returning proper HTTP status codes improves API usability and debugging.
Custom exceptions help handle missing resources cleanly.
Use @ResponseStatus(HttpStatus.NOT_FOUND) or exception handlers to send 404 status.
Clear error messages improve user experience and debugging.