十二,Spring Boot 异常处理(自定义异常页面,全局异常,自定义异常)

news2024/11/18 7:34:03

十二,Spring Boot 异常处理(自定义异常页面,全局异常,自定义异常)

文章目录

  • 十二,Spring Boot 异常处理(自定义异常页面,全局异常,自定义异常)
  • 1. 基本介绍
  • 2. 自定义异常页面
  • 3. 全局异常
  • 4. 自定义异常
  • 5. 补充:拦截器 VS 过滤器
  • 6. 总结:
  • 7. 最后:


1. 基本介绍

默认情况下,Spring Boot 提供 / error 处理所有的错误的映射,也就是说当出现错误时,
Spring Boot 底层会请求转发到 /error 这个映射。
注意是:请求转发,不是重定向的。

Spring Boot 它是有自己的默认的处理机制的,在你创建的一个 Spring Boot 项目去访问一个没有的路径会发现,Spring Boot 它是会弹出来这样的信息。

在这里插入图片描述

这是 Spring Boot 给我们内置好的,编写好的,默认配置好的 错误信息页面。

如下是 Spring Boot 检索,显示对应错误页面存放位置的结构视图:官网地址:https://docs.spring.io/spring-boot/reference/web/reactive.html#web.reactive.webflux.error-handling.error-pages

在这里插入图片描述

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>
src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.mustache
             +- <other templates>

一旦项目发生了错误,Spring Boot 会根据对应错误状态码,上述的结构路径,上找到对应的错误页面。

2. 自定义异常页面

根据上述的说明,我们根据在 Spring Boot 默认错误页面的检索路径结构,创建对应的目录,同时存放对应的错误页面。如下图所示:

在这里插入图片描述

自定义 404.html,500.html, 4xx.html ,5xx.html 当发生相应错误时,显示自定义的页面信息.

首先,我们先定义前端错误的 4开头 的错误页面。

在这里插入图片描述

在定义两个后端错误的 5 开头 的错误页面。

在这里插入图片描述

编写好之后,我们就可以模拟错误异常,试试,Spring Boot是否会走我们的自定义的错误页面,在前端展示出来

测试:4开头的,前端错误

在这里插入图片描述

在这里插入图片描述

测试: 5开头的后端错误的

在这里插入图片描述

3. 全局异常

全局异常:就是作用于整个项目的异常的,也可以是整个项目的异常页面。

@ControllerAdvice + @ExceptionHandler 这两个注解定义全局异常。

在这里插入图片描述

在这里插入图片描述

底层是 ExceptionHandlerExceptionResolver 支持的,不可以省略其它的。

在这里插入图片描述

定义一个全局异常。

在这里插入图片描述

package com.rainbowsea.springboot.exception;


import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Slf4j
@ControllerAdvice  // 使用它可以标识一个全局异常处理器/对象
public class GlobalExceptionHandler {
    // 1.编写方法,处理指定异常,比如:我们处理算术异常,可以指定多个异常
    // 2. 这里要处理的异常,由程序员来指定
    // 3. Exception e : 表示异常发生后,传递的异常对象
    // 4. Model model : 可以将我们的异常信息,放入 model ,再放入到请求域当中,并传递显示页面

    @ExceptionHandler({ArithmeticException.class, NullPointerException.class})
    public String handleAritException(Exception e, Model model) {

        log.info("异常信息={}",e.getMessage());  // 自定义的异常也是可以获取到的
        // 这里老师将发生的异常放入到model,可以再错误页面取出显示
        model.addAttribute("msg",e.getMessage());
        return "/error/global";  // 视图地址
    }
}

在这里插入图片描述

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>全局异常</title>
</head>
<body>
<h1>全局异常处理/错误,发生:)</h1>
异常/错误信息: <h1 th:text="${msg}"></h1>

</body>
</html>

运行测试:

在这里插入图片描述

注意:全局异常> 自定义异常>内置异常 的优先级

当一个异常,即在自定义异常当中,也在全局异常当中定义处理了,那么Spring Boot 优先走 全局异常/(全局异常的页面)

在这里插入图片描述

当发生ArithmeticException,NullPointerException,不使用默认异常的机制,匹配的 xxx.html,而是显示全局异常机制指定的错误页面。所以,全局异常可以说是最高优先级了。

4. 自定义异常

如果 Spring Boot 提供的异常不能满足开发需求,程序员也可以自定义异常。

  1. @ResponseStatus + 自定义异常。

在这里插入图片描述

  1. 底层是 ResponseStatusExceptionResolver。

在这里插入图片描述

  1. 当抛出自定义异常后,仍然会根据状态码,去匹配使用 xxx.html 显示。

关于自定义异常,我们在Java基础中是讲解过 => 融合贯通

  • @ResponseStatus(value = HttpStatus.FORBIDDEN) : 表示发生 AccessException异常,我们通过http
  • 协议返回的状态码 403
  • 这个状态码和自定义异常的对应关系是由程序员来决定【尽量合理来设置】

演示: 自定义一个异常AccessException,当用户访问某个无权访问的路径时,抛出该异常,显示自定义异常状态。

下面我们就自定义一个名为:AccessException 的异常,该自定异常的状态码为:

在这里插入图片描述

在这里插入图片描述

package com.rainbowsea.springboot.exception;


import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * 关于自定义异常,我们在Java基础中是讲解过 => 融合贯通
 *
 * @ResponseStatus(value = HttpStatus.FORBIDDEN) : 表示发生 AccessException异常,我们通过http
 * 协议返回的状态码 403
 * 这个状态码和自定义异常的对应关系是由程序员来决定【尽量合理来设置】
 */

@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class AccessException extends  RuntimeException{

    // 老师提供一个构造器,可以指定信息
    public AccessException(String message) {
        super(message);
        System.out.println("AccessException 有参数构造方法被调用");
    }

    // 显示的定义一个无参构造器
    public AccessException() {
        System.out.println("AccessException 无参数构造方法被调用");

    }
}

运行测试:

在这里插入图片描述

package com.rainbowsea.springboot.controller;


import com.rainbowsea.springboot.exception.AccessException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class MyErrorController {

    // 编写方法, 模拟一个AccessException
    @GetMapping("/err3")
    public String err3(String name) {

        // 如果用户不是tom,我们就认为:无权访问-模拟
        if (!"tom".equals(name)) {
            throw new AccessException("我们自己定义的异常");
            // 这里编写了放入的信息new AccessException("我们自己定义的异常") ,可以进行在后面放入
            // 到前端获取到,并显示出来。
            /*
            log.info("异常信息={}",e.getMessage());  // 自定义的异常也是可以获取到的
        // 这里老师将发生的异常放入到model,可以再错误页面取出显示
        model.addAttribute("msg",e.getMessage());
             */
        }

        return "manage"; // 视图地址
    }

}

执行效果如图:浏览器: http://locathos:8080/err3

在这里插入图片描述

在这里插入图片描述

简单的说:其实就是我们在 java se 当中学习到自定义异常处理

如果把自定义异常类型,放在全局异常回来,那么仍然走全局异常处理机制。
简单的说:我们自定义的异常类型,也是可以放到全局异常当中的。

在这里插入图片描述

运行测试:注意:全局异常的优先级比自定义异常更高,所以当一个异常,即定义在了“自定义异常” ,也定义在了“全局异常”当中时,优先执行全局异常的错误页面

运行测试:

在这里插入图片描述

5. 补充:拦截器 VS 过滤器

  • 使用范围不同:
  1. 过滤器实现是 javax.servlet.Filter 接口,而这个接口在 Servlet 规范中定义的,也就是说,过滤器 Filter 的使用依赖于 Tomcat 等容器,Filter 只能在 web 程序中使用。
  2. 拦截器(Interceptor) 它是一个 Spring 组件,并由 Spring 容器管理,并不依赖 Tomcat 等容器,是可以单独使用的,不仅能应用在 Web 程序中,而可以用于 Application 等程序中。
  • 过滤器 和 拦截器 的触发时机不同:

在这里插入图片描述

  1. 过滤器 Filter 是在请求进入容器后,但在进入 Servlet 之前进行预处理。请求结束时 Servlet 处理完以后。
  2. 拦截器 Interceptor 是在请求进入 servlet 后,在进入 Controller 控制器之后进行预处理的,Controller 中渲染了对应的视图之后,请求结束。
  • 说明:过滤器不会处理请求转发,拦截器会处理请求转发。
  1. 说明:过滤器不会处理请求转发,拦截器会处理请求转发。因为过滤器是自己内部进行过滤转发的,会先找自己同一层的内部的映射,如果没有找到才会走拦截器需要的。
  2. 至于过滤器和拦截器的原理和机制,过滤器在JavaWeb 有所说明,大家可以移步至✏️✏️✏️ JavaWeb 中 Filter过滤器-CSDN博客

6. 总结:

  1. 默认情况下,Spring Boot 提供 / error 处理所有的错误的映射,也就是说当出现错误时,
    Spring Boot 底层会请求转发到 /error 这个映射。**注意是:请求转发,不是重定向的。 **
  2. 稍微记忆一下,Spring Boot,显示对应错误页面存放位置的结构视图:官网地址:https://docs.spring.io/spring-boot/reference/web/reactive.html#web.reactive.webflux.error-handling.error-pages

在这里插入图片描述

  1. 自定义异常错误页面,要根据 Spring Boot检索的错误页面的目录,来存放错误该错误页面的文件

  2. 全局异常:就是作用于整个项目的异常的,也可以是整个项目的异常页面。

    @ControllerAdvice + @ExceptionHandler 这两个注解定义全局异常。

  3. 注意:全局异常(/全局异常错误页面)> 自定义异常(/自定义异常错误页面)>内置异常(/内置异常错误页面)的优先级

  4. 注意:拦截器和过滤器的区别。

7. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2136612.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LineageOS刷机教程

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ LineageOS 是一个基于 Android 开源项目&#xff08;AOSP&#xff09;的开源操作系统&#xff0c;主要由社区开发者维护。它起源于 CyanogenMod 项目&#xff…

数据库索引底层数据结构之B+树MySQL中的页索引分类【纯理论知识,干货分享,面试必备】

目录 1、索引简介 1.1 什么是索引 1.2 使用索引的原因 2、索引中数据结构的设计 —— B树 2.1 哈希 2.2 二叉搜索树 2.3 B树 2.4 最终选择之——B树 2.4.1 B树与B树的对比(面向索引)【面试题】 3、MySQL中的页 3.1 页的使用原因 3.2 页的结构 3.2.1 页文件头和页文件…

解锁定位服务:Flutter应用中的高德地图定位

前言 在现代移动应用开发中&#xff0c;定位服务已成为一项基本功能&#xff0c;它使得应用能够获取用户的地理位置信息&#xff0c;为用户提供更加个性化的服务。 Flutter 作为跨平台的移动应用开发框架&#xff0c;支持集成多种服务&#xff0c;包括定位服务。 本文将介绍如…

HR8870:可PWM控制,4.5A直流有刷电机驱动数据手册

HR8870芯片描述 HR8870是一款直流有刷电机驱动器&#xff0c;适用于打印机、电器、工业设备以及其他小型机器。两个逻辑输入控制H桥驱动器&#xff0c;该驱动器由四个N-MOS组成&#xff0c;能够以高达4.5A的峰值电流双向控制电机。利用电流衰减模式&#xff0c;可通过对输入进行…

故障码格式解析

中&#xff0c;诊断故障码&#xff08;DTC, Diagnostic Trouble Code&#xff09;是由一个字母前缀和三个后续字符组成的。这些字母前缀根据故障所属的系统类别来区分&#xff0c;具体如下&#xff1a; B0 -- B3&#xff1a;表示车身系统&#xff08;Body&#xff09;的故障码…

Linux CTF逆向入门

1.ELF格式 我们先来看看 ELF 文件头&#xff0c;如果想详细了解&#xff0c;可以查看ELF的man page文档。 关于ELF更详细的说明&#xff1a; e_shoff&#xff1a;节头表的文件偏移量&#xff08;字节&#xff09;。如果文件没有节头表&#xff0c;则此成员值为零。 sh_offset&…

Qt 菜单、工具栏 的基本使用

效果 代码 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QToolBar> #include<QDebug> #include<QPushButton>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupU…

【JAVA入门】Day45 - 压缩流 / 解压缩流

【JAVA入门】Day45 - 压缩流 / 解压缩流 文章目录 【JAVA入门】Day45 - 压缩流 / 解压缩流一、解压缩流二、压缩流 在文件传输过程中&#xff0c;文件体积比较大&#xff0c;传输较慢&#xff0c;因此我们发明了一种方法&#xff0c;把文件里的数据压缩到一种压缩文件中&#x…

【LLMs对抗性提示:提示泄漏、非法行为、DAN、Waluigi效应、 游戏模拟器、防御策略————】

对抗性提示 目录 对抗性提示 提示注入 提示泄漏 非法行为 DAN Waluigi效应 GPT-4模拟器 游戏模拟器 防御策略 在指令中添加防御 参数化提示组件 引用和其他格式 对抗提示检测器 模型类型 参考文献 Adversarial prompting是提示工程中的一个重要主题&#xff0c…

每日OJ_牛客_NC313 两个数组的交集

目录 牛客_NC313 两个数组的交集 解析代码 牛客_NC313 两个数组的交集 两个数组的交集_牛客题霸_牛客网 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param nums1 int整型vector * pa…

统计/nginx/access.log中每个ip的访问次数,按高到低排列

/nginx/access.log具体内容长这样&#xff1a; 第一个元素就是ip。 awk {print $1} /nginx/access.log | sort | uniq -c | sort -r首先&#xff0c;awk {print $1} /nginx/access.log 从 /nginx/access.log文件的每行中提取出第一个字段。然后&#xff0c;sort 对提取出的第…

【有哪些坑】Apollo配置中心FAQ常见问题列表

使用某个框架之前&#xff0c;得先看看前辈们踩过的坑。 他人的间接经验 -> 自己的直接经验 前车之鉴&#xff0c;后事之师。比喻前人失败了&#xff0c;后人应该从中吸取教训&#xff0c;避免再犯同样的错误。 常见问题回答 1. Apollo是什么&#xff1f; Apollo&#xff…

关于STM32项目面试题01:电源

博客的风格是&#xff1a;答案一定不能在问题的后面&#xff0c;要自己想、自己背&#xff1b;回答都是最精简、最精简、最精简&#xff0c;可能就几个字&#xff0c;你要自己自信的展开。 面试官01&#xff1a;说说你知道的开关电源的拓扑结构&#xff1f; 面试官02&#xff1…

Nacos下载和启动

Nacos是什么&#xff1f; 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台 下载 https://github.com/alibaba/nacos/releases/tag/2.1.1启动 将下载好的Nacos解压缩&#xff0c;然后到bin目录下打开cmd 输入指令&#xff1a;startup.cmd -m standalone 出…

Apache DolphinScheduler 跨工作流复杂依赖功能详解

大家好&#xff0c;我叫高楚枫&#xff0c;来自阿里云 EMR 团队的开发工程师&#xff0c;同时也是 Apache DolphinScheduler 的 PMC 成员之一。 今天非常高兴能在这里和大家分享关于跨工作流复杂依赖的功能详解。 引言 在现代的数据处理和调度过程中&#xff0c;工作流的依赖…

STL_string 常用的用法

string里常用的函数与讲解使用 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ &#xff08;点击进入c关于string 的各个函数的全面讲解使用/英文版&#xff09; Iterators&#xff08;迭代器&#xff09;: begin与end&#xff1a; …

门磁模块详解(防盗感应开关 STM32)

目录 一、介绍 二、程序设计 main.c文件 gate_guard.h文件 gate_guard.c文件 三、实验效果 四、资料获取 项目分享 一、介绍 MC-38常闭式门磁开关是作为IO开关输入数字信号的&#xff0c;原理是合在一起信号是导通的 , 配合有线主机使用 不能单独使用。适用于非铁质&a…

RK3588镜像打包制作,替换文件系统

1.在开发板上安装async apt-get async 2.在另一台linux机器上执行命令拷贝文件系统 注意&#xff1a; 这里使用root权限或者账户 mkdir rootfs rsync -avx root192.168.1.3:/ rootfs 3.制作空镜像文件 先去开发板上验证自己的系统使用了多少空间&#xff0c;然后输入命令制…

grafana升级指南

已有grafana在使用&#xff0c;需要升级新版本的grafana&#xff0c;操作如下&#xff1a; 1.先把之前的grafana文件夹整个备份 2.在grafana官网下载OSS的zip版本&#xff0c;不要msi版本 3.在原来的grafana文件夹里&#xff0c;把新版本的文件夹都复制进来&#xff0c;但是…

CVE-2024-21096:MySQLDump提权漏洞分析

CVE-2024-21096是一个中等严重性的漏洞&#xff0c;它影响Oracle MySQL Server产品中的mysqldump组件。成功利用此漏洞的未认证攻击者可能对MySQL Server的数据进行未授权的更新、插入或删除操作&#xff0c;还可以读取MySQL Server可访问数据的一部分&#xff0c;并可能导致My…