9、Spring Boot——异常处理

本文介绍SpringBoot中异常处理的方法,包括使用@ControllerAdvice进行全局异常处理,自定义静态和动态异常页面,以及通过Thymeleaf展示错误信息。文章还讲解了如何自定义异常属性和视图。

在Spring Boot中对于异常的处理,提供了非常简单的方式,比如说上篇讲的@ControllerAdvice方式的全局异常处理,那是属于SpringMVC中的,如果使用的SSM想做全局异常处理就是用它。如果用的是Spring Boot就可以不需要用它了。

比如说创建一个错误的接口,该接口一运行必定会报错:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(){
         int i=1/0;
         return "hello";
    }
}

错误页面如下
在这里插入图片描述以上是一个默认的错误页面,我们也可以自定义异常页面,自定义的异常页面分为两种,一种是静态的,一种是动态的。

静态异常页面
静态异常页面时使用HTTP响应码来命名页面,例如一种是400.html,404.html,500.html…等等,另一种是直接定义一个4xx.html,表示400-499的状态都显示这个异常页面,5xx.html表示500-599的状态都显示这个异常页面。

默认是在classpath:/static/error/路径下定义相关页面:
在这里插入图片描述
这样以后发生了404的错误就会自动找到404.html页面,发生了500错误就会自动找到500.html页面
在这里插入图片描述这种是静态页面,这样挨个,枚举显然特别麻烦,所以提供了另外一种写法直接定义一个4xx.html,表示400-499的状态都显示这个异常页面,5xx.html表示500-599的状态都显示这个异常页面。
在这里插入图片描述
那么像上面这样,既有4xx又有404,既有5xx又有500,那么当发生异常的时候,它们的优先级是怎样的呢?先找精确的(404,500),再找模糊的(4xx,5xx)。但是如果用模糊的又会有新的问题,因为静态页面,页面的数据无法修改,到底发生什么错误,也无法展示出来,所以还支持另一种,动态的错误页面展示。

动态异常页面
动态异常页面,首先地引入页面模板依赖,这里引入的是Thymeleaf

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

动态异常页面的默认路径是:classpath:/templates.error

在这里面定义也一样可以定义成404、500和4xx、5xx
在这里插入图片描述还可以通过动态页面获取相应的错误信息:
在这里插入图片描述在这里插入图片描述
那么如果这个时候发生404错误,动态异常页面,静态异常页面都有,优先会找谁呢?执行和的页面顺序如下:
发生了404错误:动态的404.html——静态的404.html——动态的4xx.html——静态的4xx.html

还可以自定义自定义异常信息:
创建一个MyErrorAttribute类,继承自DefaultErrorAttributes,重写getErrorAttributes方法

@Component
public class MyErrorAttribute extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        //注意:此处的map比较特殊,它不是HashMap,它是一个UnmodifiableMap
        //所以只能读出它的数据,存储在自己的map中 操作自己的map
        Map<String,Object> map2=new HashMap<>();
        map2.put("error",map.get("error"));
        map2.put("mydata","出错了");
        return map2;
    }
}

在页面中读取mydata:
在这里插入图片描述
自定义的异常信息覆盖了原本的异常信息
在这里插入图片描述还可以自定义视图:
创建一个MyErrorViewResolver,继承自 DefaultErrorViewResolver

@Component
public class MyErrorViewResolver extends DefaultErrorViewResolver {
    public MyErrorViewResolver(ApplicationContext applicationContext, ResourceProperties resourceProperties) {
        super(applicationContext, resourceProperties);
    }

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        ModelAndView modelAndView = new ModelAndView("sp/5xx",model);

        return modelAndView;
    }
}

然后在templates下创建一个sp文件夹如下:
在这里插入图片描述运行结果如下:
在这里插入图片描述

### 实现全局异常处理Spring Boot应用中,为了提供一致性的错误响应并简化代码结构,推荐使用`@ControllerAdvice`和`@ExceptionHandler`注解来实现全局异常处理器[^1]。 #### 使用 `@ControllerAdvice` 此注解允许定义一个控制器增强器类,在其中集中管理所有可能抛出的异常情况。这不仅有助于保持控制器本身的简洁性,还使得异常逻辑易于维护和扩展[^2]。 ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse> handleResourceNotFound(final ResourceNotFoundException ex) { final ErrorResponse errorResponse = new ErrorResponse( HttpStatus.NOT_FOUND.value(), ex.getMessage() ); return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND); } } ``` 上述例子展示了当遇到特定类型的异常(如资源未找到)时返回标准化的HTTP状态码及消息体的方式[^4]。 #### 定义统一的错误响应格式 创建一个通用的数据传输对象DTO用来封装所有的API响应信息,包括但不限于: - HTTP状态码 - 用户友好的提示文字 - 时间戳或其他元数据 这样做能够确保客户端接收到的信息始终具有一致性和可预测性。 ```json { "timestamp": "2023-09-28T15:37:42Z", "status": 404, "message": "The requested resource could not be found." } ``` #### 配置自定义异常类型 对于业务特有的场景,建议开发者设计专门针对这些情形而设的新异常类别,并让它们继承于标准Java Exception或RuntimeException。这样可以在捕获阶段更精确地区分不同性质的问题所在。 ```java public class ResourceNotFoundException extends RuntimeException { public ResourceNotFoundException(String message){ super(message); } } ``` 通过这种方式,不仅可以提高系统的健壮性和用户体验质量,同时也遵循了良好的软件工程原则——即关注点分离(Separation of Concerns)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值