一、SpringBoot全局异常处理器(处理异常一)

本文介绍如何在SpringBoot项目中自定义全局异常处理器,通过创建GlobalExceptionHandler类并使用@ExceptionHandler注解,优雅地处理各种运行时异常,如ArithmeticException和ArrayIndexOutOfBoundsException,返回统一的Result对象。

一、背景

1.在Spring Boot项目中,代码出现异常会跳转到/error页面进行错误展示,对用户和前端都不友好,我们希望以友好的方式来显示异常。

二、异常演示

1.先来演示一下默认的异常处理

@RestController
public class IndexController {

    @RequestMapping("/getResult")
    public int getResult(){
        return 10 / 0;
    }

    @RequestMapping("/getResult1")
    public int getResult1(){
        int[] arr = new int[1];
        arr[1] = 2;
        return 2;
    }

    @PostMapping("/param")
    public String param(Model model){
        return (String) model.asMap().get("param");
    }
}

2.发生异常页面显示(已经处理好的)

 

三、全局异常处理器

1.下面我们就上面的问题来进行解决,首先我们配置一个全局异常处理器

@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * ExceptionHandler 的属性为异常的class对象, 如果不指定就是方法参数的class, 且同一个异常不能重复出现多个方法中
     * 此处使用ResponseBody返回json数据,也可以和Controller方法一样返回其他类型
     */
    @ResponseBody
    @ExceptionHandler
    public Result handlerException(Exception e) {
        return new Result(1000, e.getMessage());
    }
    /**
     * 一个方法可以处理多个异常, 指定多个异常的class, 但是方法参数只能是一个,即多个异常的父类
     */
    @ResponseBody
    @ExceptionHandler({ArrayIndexOutOfBoundsException.class})
    public Result handlerMathException(Exception e) {
        return new Result(2000, e.getMessage());
    }
}

2.Result

public class Result implements Serializable {

    private static final long serialVersionUID = -429942488081558386L;

    private int code;

    private String message;

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

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public int getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

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

3.分析

handlerException方法能接受的的参数很多,按需填入即可

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {

	/**
	 * Exceptions handled by the annotated method. If empty, will default to any
	 * exceptions listed in the method argument list.
	 */
	Class<? extends Throwable>[] value() default {};

}

ExceptionHandler注解的值是一个列表,应该你可以传入多种不同的Exception。你也可以指定好几个异常处理器来处理不同的异常,如下所示。

@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * ExceptionHandler 的属性为异常的class对象, 如果不指定就是方法参数的class, 且同一个异常不能重复出现多个方法中
     * 此处使用ResponseBody返回json数据,也可以和Controller方法一样返回其他类型
     */
    @ResponseBody
    @ExceptionHandler
    public Result handlerException(Exception e) {
        return new Result(1000, e.getMessage());
    }
    /**
     * 一个方法可以处理多个异常, 指定多个异常的class, 但是方法参数只能是一个,即多个异常的父类
     */
    @ResponseBody
    @ExceptionHandler({ArithmeticException.class, ArrayIndexOutOfBoundsException.class})
    public Result handlerMathException(Exception e) {
        return new Result(2000, e.getMessage());
    }
}

四、结束

上面就是简简单单的对异常的处理!!!

 

### Spring Boot 全局异常处理不生效的原因及解决方案 #### 1. 检查注解使用情况 确保全局异常处理器正确使用 `@RestControllerAdvice` 或者 `@ControllerAdvice` 注解。这两个注解用于标记一个作为全局异常处理器,其中 `@RestControllerAdvice` 是 `@ControllerAdvice` 和 `@ResponseBody` 的组合,适用于返回 JSON 响应的情况。 ```java @RestControllerAdvice public class GlobalExceptionHandler { // 异常处理逻辑... } ``` 如果仅使用了 `@ControllerAdvice` 而未添加 `@ResponseBody`,可能会导致响应体无法正常解析[^1]。 #### 2. 验证包扫描路径 确认全局异常处理器所在的包位于主应用启动所在包及其子包内。这是因为默认情况下,Spring Boot 只会对主程序启动所在包以及其下的所有子包进行组件扫描。如果不在此范围内,即使定义了全局异常处理器也不会被加载到上下文中。 例如,假设项目的结构如下: ``` com.example.demo.Application.java (main application) └── com.example.demo.controller.MyGlobalExceptionHandler.java (global exception handler) ``` 那么 MyGlobalExceptionHandler 将能被成功识别并注册;但如果放在其他位置则可能不会起作用[^3]。 #### 3. 确认方法签名匹配 检查异常处理函数的方法签名是否能够适配实际发生的异常型。即在 `@ExceptionHandler` 方法中指定的异常别应该与抛出的具体异常致。此外还需注意参数列表的设计,通常至少包含一个 Throwable 参数用来接收具体的异常实例对象。 ```java @ExceptionHandler(CustomException.class) @ResponseBody public ResponseEntity<String> handleCustomException(Throwable ex){ logger.error("Caught an exception",ex); return new ResponseEntity<>("An error occurred.", HttpStatus.INTERNAL_SERVER_ERROR); } ``` 以上代码片段展示了如何针对特定型的异常编写相应的处理逻辑,并通过日志记录下详细的堆栈信息以便后续排查问题[^4]。 #### 4. 排除第三方库干扰 有时引入某些第三方依赖可能导致原有配置失效或冲突。因此建议查看 pom.xml 文件内的 dependencies 列表,移除非必要的外部 jar 包后再测试效果。特别是那些同样提供 web 层功能增强特性的框架,如 spring-cloud-starter-openfeign 等,因为它们内部也可能包含了似的异常拦截机制从而覆盖掉原有的设置[^5]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值