SpringBoot 异常处理

8 篇文章 0 订阅

之前在 SpringBoot 参数校验 中已经简单介绍了异常的处理,在这篇文章中再系统总结一下。

1. Controller 异常捕获

在一个类上面加 @ControllerAdvice 或者 @RestControllerAdvice 注解,就是定义该类为异常处理类。如果不带任何参数,那么这个类就是全局异常处理类,例如在 SpringBoot 参数校验 中我们创建的 GlobalExceptionHandler 。有时候如果不希望捕获全局异常,可以通过给注解传递参数,指定处理的 Controller 范围:

1. basePackages :指定一个或多个包,这些包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理

@ControllerAdvice(basePackages = {"com.tfjybj.intern.provider.controller"})
public class FaultBarrier{}

2. basePackageClasses :是 basePackages 的一种变形,指定一个或多个 Controller 类,这些类所属的包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理

@ControllerAdvice(basePackageClasses = {Test.class})
public class FaultBarrier{}

3. assignableTypes :指定一个或多个 Controller 类,这些类被该 @ControllerAdvice 管理

@ControllerAdvice(assignableTypes= {Test.class})
public class FaultBarrier{}

4. annotations :指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理

@ControllerAdvice(annotations = {RestController.class})
public class FaultBarrier{}

另外还要注意下,{} 在 Java 中表示数组,例如我们想指定多个注解,可以这样用:

@ControllerAdvice(annotations = {RestController1.class, RestController2.class})
public class FaultBarrier{}

在异常处理类中,我们可以使用 @ExceptionHandler 注解定义异常处理方法,其中 value 为需要处理的异常类的 class :

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
	@ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity<ServerResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    	return ServerResponse.badRequest(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }
}

这边需要注意下, @ControllerAdvice 或者 @RestControllerAdvice 只能处理 Controller 层抛出的异常,对例如 Interceptor(拦截器)层的异常、定时任务中的异常、异步方法中的异常,不会进行处理。此外,404 的错误也是无法捕获的:

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
	@ExceptionHandler(value = NoHandlerFoundException.class)
	public ResponseEntity<ServerResponse> handleNoHandlerFoundException(NoHandlerFoundException e) {
        // @RestControllerAdvice 只能捕获 Controller 抛出的异常
        // NoHandlerFoundException 实际上是捕获不到的
        log.error("======not found 异常======");
        log.error(e.getMessage());
        return ServerResponse.notFound();
    }
}

例如我们访问一个不存在的地址,可以看到异常并没有捕获到:
在这里插入图片描述

2. 非 Controller 异常捕获

对于上面这种不是通过 Controller 抛出的异常,使用 @ControllerAdvice@RestControllerAdvice 异常处理类无法捕获到,那么如何处理 404 异常呢?本人找到了一种方案,创建一个类并实现 ErrorController 接口,就可以处理非 Controller 抛出的异常:

@RestController
@Slf4j
public class ServerErrorController implements ErrorController {
	@Override
    public String getErrorPath() {
        // 实现 ErrorController 接口必须要实现 getErrorPath 方法
        // getErrorPath 方法返回的 path,会映射到 handleError 方法
        return "/error";
    }

	@RequestMapping(value = "/error", produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<ServerResponse> handleError(HttpServletResponse response) {
    	if (response.getStatus() == 404) {
            return ServerResponse.notFound();
        } else if (response.getStatus() == 500){
            return ServerResponse.internalServerError();
        } else {
            return ServerResponse.ok(null);
        }
    }
}

在 SpringBoot 中的默认异常处理映射为 “/error”,BasicErrorController 已经默认实现了 “text/html” 的处理。如果想返回自定义 JSON 格式信息,则实现 ErrorController 接口,重写 getErrorPath 方法。这个方法返回一个 String ,也就是异常处理映射,然后增加一个 produces 为 “application/json” 的方法即可。

参考

SpringBoot中实现拦截器, 并实现对404和500等错误的拦截
Spring Boot 实现ErrorController接口处理404、500等错误页面

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
SpringBoot提供了一套默认的异常处理机制。一旦程序出现异常SpringBoot会向/error的URL发送请求,并通过BasicErrorController来处理该请求。默认情况下,SpringBoot会跳转到默认显示异常信息的页面来展示异常信息。如果我们希望将所有的异常统一跳转到自定义的错误页面,可以在src/main/resources/templates目录下创建一个名为error.html的页面。通过覆盖默认的错误页面,我们可以实现自定义的异常处理。 除了使用SpringBoot的默认配置外,还可以通过自定义错误页面来处理异常。我们可以在src/main/resources/templates目录下创建error.html页面,并将其命名为error。通过这种方式,我们可以自定义错误页面的内容和样式来展示异常信息。 在处理异常的过程中,可以关注ErrorMvcAutoConfiguration中的三个关键点。通过对SpringBoot错误处理机制源码的跟踪,我们可以更深入地了解异常处理的实现细节。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringBoot异常处理](https://blog.csdn.net/Linging_24/article/details/126077782)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [SpringBoot 异常处理详解](https://blog.csdn.net/qq_42402854/article/details/91415966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值