Mastering Global Exception Handling in Spring Boot: A Step-by-Step Guide

This article demonstrates how to implement unified global exception handling in a Spring Boot application by defining custom exceptions, creating a @RestControllerAdvice with specific @ExceptionHandler methods, and wiring sample controller endpoints to showcase both system and custom error responses.

Programmer DD
Programmer DD
Programmer DD
Mastering Global Exception Handling in Spring Boot: A Step-by-Step Guide

In a Spring Boot project you can centralize exception handling to provide user‑friendly error messages. First, define a custom exception class.

package com.example.thymeleafdemo.exception;

import lombok.Data;

@Data
public class MyBusinessException extends RuntimeException {
    private static final long serialVersionUID = 1L;
    private int code;
    private String message;

    public MyBusinessException(String message) {
        super(message);
        this.message = message;
    }

    public MyBusinessException(int code, String message) {
        super(message);
        this.code = code;
        this.message = message;
        this.code = code;
    }
}

Next, create a global exception handler using @RestControllerAdvice and @ExceptionHandler to process different exception types.

package com.example.thymeleafdemo.exception;

import com.example.thymeleafdemo.event.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.StringJoiner;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /** Handle custom exception */
    @ExceptionHandler(MyBusinessException.class)
    public Result handleBizException(MyBusinessException ex) {
        Result<Object> result = new Result<>();
        result.setCode(ex.getCode());
        result.setMessage(ex.getMessage());
        return result;
    }

    /** Handle validation errors */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        StringJoiner sj = new StringJoiner(";");
        ex.getBindingResult().getFieldErrors().forEach(x -> sj.add(x.getDefaultMessage()));
        Result<Object> result = new Result<>();
        result.setCode(505);
        result.setMessage(sj.toString());
        return result;
    }

    /** Handle missing request parameters */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result handleMissingServletRequestParameterException(MissingServletRequestParameterException ex) {
        Result<Object> result = new Result<>();
        result.setCode(506);
        result.setMessage(ex.getMessage());
        return result;
    }

    /** Handle other unknown exceptions */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception ex) {
        log.error(ex.getMessage(), ex);
        Result<Object> result = new Result<>();
        result.setCode(507);
        result.setMessage("服务器内部错误");
        return result;
    }
}

Finally, add a controller to trigger both a system exception (division by zero) and the custom exception.

package com.example.thymeleafdemo.exception;

import com.example.thymeleafdemo.event.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExceptionController {

    /** System internal error */
    @GetMapping("/exception")
    public Result testException() {
        int i = 1 / 0;
        Result<Object> result = new Result<>();
        result.setCode(200);
        result.setMessage("success");
        result.setData("cc");
        return result;
    }

    /** Custom exception */
    @GetMapping("/myException")
    public Result testMyexception() {
        throw new MyBusinessException(508, "自定义的异常");
    }
}

When the application runs, accessing http://localhost:8080/exception returns the server‑internal‑error response (see Image 1), while http://localhost:8080/myException returns the custom error message (see Image 2). The global handler masks internal details and presents concise messages to the client.

Server internal error screenshot
Server internal error screenshot
Custom exception error screenshot
Custom exception error screenshot

The unified exception handling works by using @ControllerAdvice to intercept exceptions from all controllers, applying the appropriate @ExceptionHandler method, and returning a standardized Result object to the client.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpring BootREST APIglobal exception handling
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.