In RESTful APIs, it's a best practice to return appropriate HTTP status codes for various error scenarios. In Spring Boot, if an ID is not found in the database or repository, returning a 400 Bad Request
is common when the request itself is invalid or malformed.
This article shows you how to throw a custom BadRequestException
when an ID is missing, and how to handle it cleanly using @RestControllerAdvice
.
π οΈ Step-by-Step Guide
β
1. Create a Custom Exception
java
package com.example.demo.exception;
public class BadRequestException extends RuntimeException {
public BadRequestException(String message) {
super(message);
}
}
This custom exception represents an invalid request, like a missing or non-existent ID.
β
2. Handle the Exception with a Global Handler
java
package com.example.demo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(BadRequestException.class)
public ResponseEntity<String> handleBadRequestException(BadRequestException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}
This catches any BadRequestException
thrown in your app and sends a proper HTTP 400 response.
β
3. Throw Exception in the Service Layer
java
package com.example.demo.service;
import com.example.demo.exception.BadRequestException;
import com.example.demo.model.YourEntity;
import com.example.demo.repository.YourRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class YourService {
@Autowired
private YourRepository repository;
public YourEntity findById(Long id) {
return repository.findById(id)
.orElseThrow(() -> new BadRequestException("ID " + id + " not found"));
}
}
The orElseThrow()
method ensures that if the entity isnβt found, the exception is thrown immediately.
β
4. Use the Service in Your Controller
java
package com.example.demo.controller;
import com.example.demo.model.YourEntity;
import com.example.demo.service.YourService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class YourController {
@Autowired
private YourService service;
@GetMapping("/entity/{id}")
public YourEntity getEntityById(@PathVariable Long id) {
return service.findById(id);
}
}
When a GET request is made for an entity with a non-existing ID, the client will receive:
http
HTTP/1.1 400 Bad Request
Content-Type: text/plain
ID 123 not found
π Conclusion
GoalMethodThrow 400 if ID missingCreate custom BadRequestException
Catch globallyUse @RestControllerAdvice
Clean error messagesReturn error from ResponseEntity<String>
Lightweight & scalableWorks with any RESTful controller
This approach keeps your API responses consistent and easy to debug, while giving developers clear feedback when an invalid ID is queried.