Implementing a Global Unified Exception Handler in Spring Boot
This article demonstrates how to create a reusable global exception handling mechanism for Spring Boot applications by defining a unified response class, custom business exception, error enumeration, and a @RestControllerAdvice handler, complete with code examples and testing guidance.
When developing Spring Boot applications, repetitive try‑catch‑finally blocks clutter the code and reduce readability, so a global unified exception handler is needed to centralize error processing.
Recommendation: The provided solution can be copied into a project with minimal configuration and extended to handle business‑specific exceptions with fine‑grained control.
1. Encapsulate a Unified Response Class
The AjaxResult class defines fields for success status, code, message, and data, along with constructors and static factory methods for error responses.
public class AjaxResult {
// Whether the request succeeded
private Boolean success;
// Status code
private Integer code;
// Message
private String msg;
// Data payload
private Object data;
public AjaxResult() {}
// Custom constructor
public AjaxResult(Boolean success, Integer code, String msg, Object data) {
this.success = success;
this.code = code;
this.msg = msg;
this.data = data;
}
// Factory method for custom exception result
public static AjaxResult defineError(BusinessException de) {
AjaxResult result = new AjaxResult();
result.setSuccess(false);
result.setCode(de.getErrorCode());
result.setMsg(de.getErrorMsg());
result.setData(null);
return result;
}
// Factory method for other errors
public static AjaxResult otherError(ErrorEnum errorEnum) {
AjaxResult result = new AjaxResult();
result.setMsg(errorEnum.getErrorMsg());
result.setCode(errorEnum.getErrorCode());
result.setSuccess(false);
result.setData(null);
return result;
}
// Getters and setters omitted for brevity
}2. Custom Business Exception Class
The BusinessException extends RuntimeException and carries an error code and message.
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;
/** Error status code */
protected Integer errorCode;
/** Error message */
protected String errorMsg;
public BusinessException() {}
public BusinessException(Integer errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public Integer getErrorCode() { return errorCode; }
public void setErrorCode(Integer errorCode) { this.errorCode = errorCode; }
public String getErrorMsg() { return errorMsg; }
public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; }
}3. Error Enumeration to Avoid Hard‑Coding
The ErrorEnum defines common error codes and messages.
public enum ErrorEnum {
SUCCESS(200, "成功"),
NO_PERMISSION(403, "你没得权限"),
NO_AUTH(401, "未登录"),
NOT_FOUND(404, "未找到该资源!"),
INTERNAL_SERVER_ERROR(500, "服务器异常请联系管理员");
private Integer errorCode;
private String errorMsg;
ErrorEnum(Integer errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public Integer getErrorCode() { return errorCode; }
public String getErrorMsg() { return errorMsg; }
}4. Global Exception Handler
The GlobalExceptionHandler uses @RestControllerAdvice to intercept BusinessException and generic Exception, logging the error and returning an AjaxResult.
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/** Handle custom business exceptions */
@ExceptionHandler(value = BusinessException.class)
public AjaxResult bizExceptionHandler(BusinessException e) {
log.error(e.getMessage(), e);
return AjaxResult.defineError(e);
}
/** Handle all other exceptions */
@ExceptionHandler(value = Exception.class)
public AjaxResult exceptionHandler(Exception e) {
log.error(e.getMessage(), e);
return AjaxResult.otherError(ErrorEnum.INTERNAL_SERVER_ERROR);
}
}5. Testing
After integrating the above components, invoking an endpoint that throws a BusinessException returns a JSON response like
{"success":false,"code":403,"msg":"你没得权限","data":null}, confirming that the global handler works as expected.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
