Spring Boot统一异常处理详解

下面将以“Spring Boot统一异常处理详解”为主题,为大家详细讲解该主题的完整攻略。

下面将以“Spring Boot统一异常处理详解”为主题,为大家详细讲解该主题的完整攻略。

一、什么是 Spring Boot 统一异常处理

Spring Boot 统一异常处理指在 Spring Boot 应用程序中,通过设置全局异常处理器,来捕获和处理抛出的异常信息。通过统一异常处理,我们可以将系统中可能出现的各种异常信息进行分类、归纳和统一处理,并返回标准化的异常响应结果,从而为系统开发和运维提供了极大的便利和效率。

二、Spring Boot 统一异常处理的实现方式

一般来说,Spring Boot 实现全局异常处理有两种方式:

1.使用 @ControllerAdvice 实现

@ControllerAdvice 注解是 Spring 框架中提供的一个基于 AOP 可以被所有使用 @RequestMapping 注解的方法共享的增强控制器,它作用于全局,可以用于捕获和处理在控制器中抛出的异常信息。

第一步:定义一个增强控制器

@ControllerAdvice
public class GlobalExceptionHandler {
    // 异常处理逻辑代码
}

第二步:在 GlobalExceptionHandler 类中添加处理具体异常的方法

@ControllerAdvice
public class GlobalExceptionHandler {
    /**
    * 处理运行时异常
    */
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public CommonResult handleRuntimeException(RuntimeException e) {
        log.error("运行时异常:", e);
        return CommonResult.error("系统异常,请稍后再试!");
    }
}

第三步:测试异常处理效果

@RequestMapping("/getUser")
public CommonResult getUser(@RequestParam("id") Long id) {
    User user = userService.getUserById(id);
    return CommonResult.success(user);
}

如果 UserService 中的 getUserById(id) 方法抛出异常,则会被 GlobalExceptionHandler 捕获,并返回统一的异常响应结果。

2.创建一个类实现 ErrorController 接口

实现 ErrorController 接口可以获取到所有的错误信息。我们也可以自定义错误信息,处理后输出到统一的格式。

第一步:创建全局异常处理器类

@RestController
public class GlobalExceptionHandler implements ErrorController {

    /**
     * 实现 ErrorController 接口,获取错误路径
     */
    @Override
    public String getErrorPath() {
        return "/error";
    }

    /**
     * 捕获所有的异常,并进行处理
     */
    @RequestMapping("/error")
    public CommonResult handleError(HttpServletRequest request) {
        // 获取错误状态码
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");

        // 根据状态码,返回相应信息
        if (statusCode == 500) {
            return CommonResult.error("系统异常,请稍后再试!");
        } else if (statusCode == 404) {
            return CommonResult.error("未找到资源,请检查请求地址是否正确!");
        } else {
            return CommonResult.error("系统错误,请稍后再试!");
        }
    }
}

第二步:测试异常处理效果

@RequestMapping("/getUser")
public CommonResult getUser(@RequestParam("id") Long id) {
    User user = userService.getUserById(id);
    return CommonResult.success(user);
}

如果 UserService 中的 getUserById(id) 方法抛出异常,则会被 GlobalExceptionHandler 捕获,并返回统一的异常响应结果。

三、Spring Boot 统一异常处理示例

示例一

先定义一个测试 Controller:

@RestController
public class TestController {

    @RequestMapping("/test1")
    public String test1(Integer num) {
        int i = 1 / num;
        return "result:" + i;
    }
}

在访问 http://localhost:8080/test1?num=0 时,由于参数 num 为0,会出现异常信息,此时可以通过全局异常处理进行捕获和统一处理。

使用 @ControllerAdvice 实现全局异常处理:

@ControllerAdvice
public class GlobalExceptionHandler1 {
    /**
    * 处理除数为0异常
    */
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public String handleDivideZeroException(ArithmeticException e) {
        return "参数错误,除数不能为0";
    }
}

使用实现 ErrorController 接口实现全局异常处理:

@RestController
public class GlobalExceptionHandler2 implements ErrorController {

    /**
     * 实现 ErrorController 接口,获取错误路径
     */
    @Override
    public String getErrorPath() {
        return "/error";
    }

    /**
     * 处理除数为0异常
     */
    @RequestMapping("/error")
    public String handleDivideZeroException(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == 500)
            return "系统错误,请稍后再试";
        else
            return "参数错误,除数不能为0!";
    }
}

示例二

定义一个自定义异常类,然后在 Controller 中抛出该异常,并通过全局异常处理进行捕获和处理。

定义自定义异常类:

public class CustomException extends RuntimeException {
    private Integer code;
    private String message;

    public CustomException(Integer code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

定义一个测试 Controller:

@RestController
public class TestController {

    @RequestMapping("/test2")
    public String test2(Integer num) {
        if (num == null)
            throw new CustomException(1001, "参数不能为空");
        return "result:" + num;
    }
}

使用 @ControllerAdvice 实现全局异常处理:

@ControllerAdvice
public class GlobalExceptionHandler3 {
    /**
    * 处理自定义异常
    */
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public CommonResult handleCustomException(CustomException e) {
        log.error("自定义异常:", e);
        return CommonResult.error(e.getCode(), e.getMessage());
    }
}

使用实现 ErrorController 接口实现全局异常处理:

@RestController
public class GlobalExceptionHandler4 implements ErrorController {

    /**
     * 实现 ErrorController 接口,获取错误路径
     */
    @Override
    public String getErrorPath() {
        return "/error";
    }

    /**
     * 处理自定义异常
     */
    @RequestMapping("/error")
    public CommonResult handleCustomException(HttpServletRequest request) {
        // 获取错误状态码
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");

        // 根据状态码,返回相应信息
        if (statusCode == 500) {
            return CommonResult.error("系统异常,请稍后再试!");
        } else if (statusCode == 404) {
            return CommonResult.error("未找到资源,请检查请求地址是否正确!");
        } else if (statusCode == 1001) {
            return CommonResult.error(statusCode, "参数不能为空!");
        } else {
            return CommonResult.error("系统错误,请稍后再试!");
        }
    }
}

以上就是 Spring Boot 统一异常处理的详细攻略,希望能对大家有所帮助。

本文标题为:Spring Boot统一异常处理详解

基础教程推荐