Backend Development 9 min read

Global Exception Handling in Spring Boot: Techniques and Code Examples

This article explains how to efficiently handle exceptions in Spring Boot applications by using @ControllerAdvice and @ExceptionHandler annotations, providing step-by-step code examples for custom global exception classes, error response structures, and handling specific exceptions such as business, null pointer, and type conversion errors.

Top Architecture Tech Stack
Top Architecture Tech Stack
Top Architecture Tech Stack
Global Exception Handling in Spring Boot: Techniques and Code Examples

In daily project development, exceptions are common; handling them efficiently improves debugging and code readability.

SpringBoot already provides basic exception handling, but developers often need a unified approach.

Global Exception Handling Method 1

Using @ControllerAdvice to enable global exception handling and @ExceptionHandler to define methods for specific exception types.

1.1 Custom Global Exception Class

/**
 * @description 自定义异常处理
 * @author DT
 * @version v1.0 */
@ControllerAdvice
public class MyExceptionHandler {
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public String exceptionHandler(Exception e) {
        System.out.println("全局异常捕获>>>:" + e);
        return "全局异常捕获,错误原因>>>" + e.getMessage();
    }
}

1.2 Manually Throwing Exceptions

@GetMapping("/getById/{userId}")
public CommonResult
getById(@PathVariable Integer userId) {
    // 手动抛出异常
    int a = 10/0;
    return CommonResult.success(userService.getById(userId));
}

These approaches expose raw exception messages, which may be unfriendly to users.

Global Exception Handling Method 2

2.1 Define Base Error Interface

public interface BaseErrorInfoInterface {
    String getResultCode();
    String getResultMsg();
}

2.2 Define Enum for Error Codes

public enum ExceptionEnum implements BaseErrorInfoInterface {
    SUCCESS("2000","成功!"),
    BODY_NOT_MATCH("4000","请求的数据格式不符!"),
    SIGNATURE_NOT_MATCH("4001","请求的数字签名不匹配!"),
    NOT_FOUND("4004","未找到该资源!"),
    INTERNAL_SERVER_ERROR("5000","服务器内部错误!"),
    SERVER_BUSY("5003","服务器正忙,请稍后再试!"),
    PARAMS_NOT_CONVERT("4002","类型转换不对!");
    // getters omitted
}

2.3 Custom Business Exception

public class BizException extends RuntimeException {
    private String errorCode;
    private String errorMsg;
    // constructors and getters/setters
}

2.4 Standard Response Wrapper

public class ResultResponse {
    private String code;
    private String message;
    private Object result;
    // static factory methods success() and error()
}

2.5 Global Exception Handler Implementation

@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public ResultResponse bizExceptionHandler(HttpServletRequest req, BizException e) {
        logger.error("发生业务异常!原因是:{}", e.getErrorMsg());
        return ResultResponse.error(e.getErrorCode(), e.getErrorMsg());
    }

    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public ResultResponse exceptionHandler(HttpServletRequest req, NullPointerException e) {
        logger.error("发生空指针异常!原因是:", e);
        return ResultResponse.error(ExceptionEnum.BODY_NOT_MATCH);
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultResponse exceptionHandler(HttpServletRequest req, Exception e) {
        logger.error("未知异常!原因是:", e);
        return ResultResponse.error(ExceptionEnum.INTERNAL_SERVER_ERROR);
    }
}

2.6 Test Controllers

@PostMapping("/add")
public boolean add(@RequestBody User user) {
    if (user.getName() == null) {
        throw new BizException("-1","用户姓名不能为空!");
    }
    return true;
}

@PutMapping("/update")
public boolean update(@RequestBody User user) {
    String str = null;
    str.equals("111"); // triggers NullPointerException
    return true;
}

@DeleteMapping("/delete")
public boolean delete(@RequestBody User user) {
    Integer.parseInt("abc123"); // triggers NumberFormatException
    return true;
}

2.7 Handling NumberFormatException

@ExceptionHandler(value = NumberFormatException.class)
@ResponseBody
public ResultResponse exceptionHandler(HttpServletRequest req, NumberFormatException e) {
    logger.error("发生类型转换异常!原因是:", e);
    return ResultResponse.error(ExceptionEnum.PARAMS_NOT_CONVERT);
}

By centralizing exception handling, code duplication is reduced, maintenance becomes easier, and developers can quickly locate bugs, greatly improving development efficiency.

backendJavaAnnotationsSpringBootRESTExceptionHandling
Top Architecture Tech Stack
Written by

Top Architecture Tech Stack

Sharing Java and Python tech insights, with occasional practical development tool tips.

0 followers
Reader feedback

How this landed with the community

login 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.