Syllabus / Java / Phase 6: Career Launch — Spring Boot, Projects, Interview Prep (Days 27–30)
Intermediate

Exception Handling, Validation & Building a Capstone Project

📂 Phase 6: Career Launch — Spring Boot, Projects, Interview Prep (Days 27–30) · Java

A professional Spring Boot API never lets a raw stack trace leak back to the client, and it never trusts incoming data blindly. Two things make an API feel production-grade: consistent global exception handling, and request validation — and combining both inside one capstone project is how you turn everything from this phase into something interview-ready.

The Problem With Default Error Responses

Without handling, an unhandled exception in Spring Boot returns a generic, unhelpful 500 error with an internal stack trace exposed — not something you want in a real API or in front of an interviewer.

Global Exception Handling with @ControllerAdvice

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(StudentNotFoundException.class)
    public ResponseEntity handleNotFound(StudentNotFoundException ex) {
        ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity handleGeneric(Exception ex) {
        ErrorResponse error = new ErrorResponse("INTERNAL_ERROR", "Something went wrong");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
    }
}

A custom exception is just a plain class extending RuntimeException:

public class StudentNotFoundException extends RuntimeException {
    public StudentNotFoundException(String message) {
        super(message);
    }
}

Validating Incoming Data with @Valid

Bean Validation annotations on a DTO (Data Transfer Object) let Spring reject bad input automatically, before it ever reaches your service logic.

public class StudentRequestDto {

    @NotBlank(message = "Name is required")
    private String name;

    @Email(message = "Email must be valid")
    private String email;

    @Min(value = 18, message = "Age must be at least 18")
    private Integer age;

    // Getters and setters
}
@PostMapping
public Student create(@Valid @RequestBody StudentRequestDto dto) {
    return studentService.createStudent(dto);
}
Why a DTO instead of the entity directly? Exposing your JPA entity straight through the API ties your database schema to your API contract — change one and you risk breaking the other. A DTO keeps the two independent.

Common Validation Annotations

AnnotationChecks
@NotNullValue must not be null
@NotBlankString must not be null or empty/whitespace
@Size(min, max)String/collection length within range
@EmailValue must be a valid email format
@Min / @MaxNumeric value within bounds

Putting It All Together: The Capstone Project

By this point you have every piece needed to build one complete, interview-ready project — a Student Management REST API (or a Task Manager, if you prefer):

  • Entity + Repository + Service + Controller (Day 28)
  • DTOs with validation on every incoming request (this lesson)
  • A global exception handler returning consistent error JSON (this lesson)
  • MySQL as the backing database (Day 28)
// Example consistent error response shape returned for every failure
{
  "errorCode": "NOT_FOUND",
  "message": "Student with id 14 not found"
}

Push the finished project to GitHub with a clear README explaining the architecture — this becomes the project you walk an interviewer through on Day 30.

Interview tip: Interviewers consistently ask "why did you choose this approach?" about your own project decisions far more than they ask abstract theory questions — be ready to justify why you used a DTO instead of the entity, or why you centralized exception handling instead of try-catch in every controller method.