Spring MVC异常处理【单个控制异常处理器、全局异常处理器、自定义异常处理器】

news2024/12/23 2:20:14

目录

一、单个控制器异常处理

1.1 控制器方法

1.2 编写出错页面

1.3 测试结果

二、全局异常处理

2.1 一个有异常的控制器类

2.2 全局异常处理器类

2.3 测试结果 

三、自定义异常处理器

3.1 自定义异常处理器

3.2 测试结果

往期专栏&文章相关导读 

1. Maven系列专栏文章

2. Mybatis系列专栏文章

3. Spring系列专栏文章

4. Spring MVC系列专栏文章   


一、单个控制器异常处理

在系统当中, Dao、Service、Controller层代码出现都可能抛出异常。如果哪里产生异常就在哪里处理,则会降低开发效率。所以一般情况下我们会让异常向上抛出,最终到达DispatcherServlet中,此时SpringMVC提供了异常处理器进行异常处理,这样可以提高开发效率

处理单个Controller的异常:

1.1 控制器方法

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MyController {

    // 处理单个Controller异常
    @RequestMapping("/t1")
    public String t1(){
        String str = null;
        // str.length();
        // int flag = 1/0;
        int []arr = new int[1];
        arr[2] = 10;
        return "index";
    }

    /**
     * 异常处理方法
     * @param ex 异常对象
     * @param model 模型对象
     * @return
     */
    // 添加@ExceptionHandler,表示该方法是处理异常的方法,属性为处理的异常类
    @ExceptionHandler({java.lang.NullPointerException.class,java.lang.ArithmeticException.class})
    public String exceptionHandler1(Exception ex, Model model){
        // 向模型中添加异常对象
        model.addAttribute("msg",ex);
        // 跳转到异常页面
        return "error";
    }

    // 方法一不能处理的异常交给方法二处理
    @ExceptionHandler({java.lang.Exception.class})
    public String exceptionHandler2(Exception ex,Model model){
        model.addAttribute("msg",ex);
        return "error2";
    }
}

从控制器方法我们可以知道,如果出现算术错误类的话则返回错误页面1,否则都返回给错误页面2.。并且把错误信息传到前端。

1.2 编写出错页面

这里编写两个错误页面,为了是测试控制器是否成功知道出现的是哪一个错误。

错误页面1

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>出错了!</title>
</head>
<body>
<h3>ERROR 发生异常! ${msg}</h3>
</body>
</html>

严重错误页面2

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>出错了!</title>
</head>
<body>
<h3>ERROR2 发生严重异常! ${msg}</h3>
</body>
</html>

1.3 测试结果

OK,这里测试运行一下,上面的应该返回的是错误页面2,因为出现的错误是数组越界访问。

OK,我们再换一个错误,注释掉以下几行,再重新运行一遍是否跳到错误页面1,因为这里出现的算术错误。

OK,可以看到这里确实返回错误页面1出来了

二、全局异常处理

在控制器中定义异常处理方法只能处理该控制器类的异常,要想处理所有控制器的异常,需要定义全局异常处理类。如何体现这个全局异常处理呢,我们需要新建一个异常类,一个全局异常处理类,错误页面就按照上面两个即可。

2.1 一个有异常的控制器类

这里就用一个数组越界的错误类。

package com.example.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

// 编写另一个有异常的控制器类
@Controller
public class MyController2 {
    @RequestMapping("/t2")
    public String t1(){
        String str = null;
        // str.length();
        // int flag = 1/0;
        int []arr = new int[1];
        arr[2] = 10;
        return "index";
    }
}

2.2 全局异常处理器类

从控制器方法我们可以知道,如果出现算术错误类的话则返回错误页面1,否则都返回给错误页面2.。并且把错误信息传到前端。

package com.example.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

// 全局异常处理类:添加@ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 异常处理方法
     * @param ex 异常对象
     * @param model 模型对象
     * @return
     */
    // 添加@ExceptionHandler,表示该方法是处理异常的方法,属性为处理的异常类
    @ExceptionHandler({java.lang.NullPointerException.class,java.lang.ArithmeticException.class})
    public String exceptionHandler1(Exception ex, Model model){
        // 向模型中添加异常对象
        model.addAttribute("msg",ex);
        // 跳转到异常页面
        return "error";
    }

    // 方法一不能处理的异常交给方法二处理
    @ExceptionHandler({java.lang.Exception.class})
    public String exceptionHandler2(Exception ex,Model model){
        model.addAttribute("msg",ex);
        return "error2";
    }
}

2.3 测试结果 

OK,访问路径:http://localhost:8080/t2

OK,确实和我们预料的一样,全局异常处理类发挥了作用。

三、自定义异常处理器

以上方式都是使用的SpringMVC自带的异常处理器进行异常处理,我们还可以自定义异常处理器处理异常:

3.1 自定义异常处理器

package com.example.controller;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 自定义异常处理器实现HandlerExceptionResolver接口,并放入Spring容器中
@Component
public class MyExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        if(e instanceof NullPointerException){
            modelAndView.setViewName("error");
        }
        else {
            modelAndView.setViewName("error2");
            System.out.println("我自己的异常处理器");
        }
        modelAndView.addObject("msg",e);
        return modelAndView;
    }
}

3.2 测试结果

OK,为了体现自定义的异常处理器,我把全局异常处理器删除再重新启动服务器,访问上面那个有异常控制类。可以看到自定义异常处理类发挥了作用。

往期专栏&文章相关导读 

     大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。

1. Maven系列专栏文章

Maven系列专栏Maven工程开发
Maven聚合开发【实例详解---5555字】

2. Mybatis系列专栏文章

Mybatis系列专栏MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发---实现增删查改和动态SQL
MyBatis注解开发---实现自定义映射关系和关联查询

3. Spring系列专栏文章

Spring系列专栏Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

4. Spring MVC系列专栏文章   

SpringMVC系列专栏Spring MVC简介附入门案例
Spring MVC各种参数获取及获取方式自定义类型转换器和编码过滤器
Spring MVC获取参数和自定义参数类型转换器及编码过滤器
Spring MVC处理响应附案例详解
Spring MVC相关注解运用 —— 上篇

Spring MVC相关注解运用 —— 中篇

Spring MVC相关注解运用 —— 下篇
Spring MVC多种情况下的文件上传
Spring MVC异步上传、跨服务器上传和文件下载
Spring MVC异常处理【单个控制异常处理器、全局异常处理器、自定义异常处理器】
Spring MVC拦截器和跨域请求
SSM整合案例【C站讲解最详细流程的案例】

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

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

相关文章

【并发编程二十二】通过进程名字杀死进程TerminateProcess

【并发编程二十二】通过进程名字杀死进程TerminateProcess 一、代码二、杀进程失败时&#xff0c;检查1、OpenProcess的参数2、UpdatePrivilege提升优先级3、以管理员方式&#xff0c;启动进程 三、启动进程失败1、由于找不到vcruntime140d.dll&#xff0c;无法继续执行代码。2…

ScaleBit 与 NFTScan 达成安全生态合作伙伴关系

7 月初&#xff0c;ScaleBit 与 NFT 基础设施服务商 NFTScan 正式达成安全生态战略合作&#xff0c;携手促进 NFT 生态的安全性。 NFTScan 作为全球领先的 NFT 基础设施服务商&#xff0c;旨在为 Web3 用户和开发者提供专业的一站式 NFT 基础设施服务。用户可以通过它搜索、查看…

3. CSS-定位

absolute和relative依据什么定位? relative依据自身定位,absolute 依据最近一层的定位元素定位 (定位元素是指开启了absolute relative fixed的父元素,没有就是根元素body) 居中对齐的实现方式:详情看这篇博客

10、添加osmbuilding全球建筑模型

本节演示使用CCesium库添加osm的全球建筑模型。在第四节的例子中修改。 1、修改鼠标点击事件&#xff0c;创建osmbuilding并添加到地图中。 aggregator->tileset Cesium::CreateOsmBuildings::createOsmBuildings(false); aggregator->viewer->_scene->primitiv…

linux中安装minio

在 opt 下创建 minio 目录 mkdir minio 上传安装包到 /opt/minio 目录 进入目录 cd minio 授权minio chmod 777 minio 启动minio nohup ./minio server --address 0.0.0.0:9000 --console-address 0.0.0.0:9090 /opt/minio/data > /opt/minio/minio.log 2>&1…

Nautilus Chain NautDID NFT 将上主网,Layer3 数字身份时代开启

Nautilus Chain 是行业内首个模块化 Layer3 链&#xff0c;其采用Celestia模块化底层&#xff0c;并通过ZK Rollup 技术来增加隐私。Nautilus Chain 允许开发者以定制化的方式&#xff0c;通过 Nnautilus 开发者可以更广泛化的在一揽子的模块中&#xff0c;选择适合自己的方案&…

1、shell脚本的基本知识——变量、字符串、循环

目录 一、基本知识 二、 shell的变量和赋值 1、注意 2、变量的种类 3、例子 三、特殊符号 1、单引号、双引号、反引号 2、管道 3、大于号>和小于号<(重定向) &#xff08;1&#xff09;常识 &#xff08;2&#xff09;应用&#xff08;描述符在右边的时候&#x…

JavaWeb(6)——前端工程化(AJAX 和VUE入门)

一、AJAX快速入门 而原生的Ajax请求的代码编写起来还是比较繁琐的&#xff0c;所以接下来我们学习一门更加简单的发送Ajax 请求的技术Axios 。Axios是对原生的AJAX进行封装&#xff0c;简化书写。 Axios官网是&#xff1a;起步 | Axios 中文文档 | Axios 中文网 (axios-http.c…

Spark中为什么Left join比Full join 快

背景 最近在调优的过程中&#xff0c;发现了left outer join比full outer join快很多的情况&#xff0c; 具体的sql如下&#xff1a; from db.baseTb1 base join db.tb1 a on base.id a.idfull outer join db.tbl2 b on a.id b.id full outer join db.tbl3 c on b.id c…

基于Java+SpringBoot+vue的任务追踪管理系统设计与实现

博主介绍&#xff1a;✌擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案…

【代码随想录 | Leetcode | 第五天】链表 | 移除链表元素 | 设计链表 | 203-707

前言 欢迎来到小K的Leetcode|代码随想录|专题化专栏&#xff0c;今天将为大家带来移除链表元素和设计链表的分享✨ 目录 前言203. 移除链表元素707. 设计链表总结 203. 移除链表元素 ✨题目链接点这里 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所…

[Arduino] ESP32开发 - UDP收发数据

UDP 通信 UDP发送数据 再开始测试之前&#xff0c;请使用手机打开一个热点&#xff0c;并把电脑连接到手机热点上&#xff0c;这样子在后续测试中 ESP32 和电脑就会在同一个局域网&#xff08;手机热点可以使用路由器代替&#xff09; 新建任意文件&#xff0c;填入以下代码 …

linux日志文件

前言&#xff1a; 无论管理什么系统&#xff0c;对日志文件的监控、调用、管理都是其中重要的一部分。服务器问题的解决都是从查看系统&#xff08;错误&#xff09;日志开始的 一、作用&#xff1a; linux运行的程序通常把系统的消息和错误写入对应的日志文件&#xff0c;如L…

浙大数据结构第三周之03-树3 Tree Traversals Again

题目详情&#xff1a; An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2)…

Vue列表过滤(计算属性和监听属性实现)

filter&#xff1a; 过滤器 indexOf()&#xff1a;是否包含某某值 <body> <div id"root"><!--遍历数组--><h2>人员列表</h2><input type"text" placeholder"请输入名字" v-model"keyWord"><ul…

封装实验环境,助力观察MySQL binlog事件

维多利亚女王时代是聚积的年代&#xff1b;不仅仅是物质财富的聚积&#xff0c;而且是每一个国家能增强国力的所有因素与要素的增加和聚积。教育惠及社会各个阶层。科学打开大自然的无限宝库。宝库之门一扇一扇被打开。阴暗而神秘的宝库一个个被照亮&#xff0c;一个个被开发&a…

Gitlab 使用 docker buildx 多重构建镜像上传私有 Harbor与 Dockerhub

文章目录 1. 预备条件2. 安装 docker2.1 安装 docker buidx2.2 docker 配置2.3 安装 Buildx2.4 安装模拟器 3. 安装 git4. 安装 gitlab5. 部署 gitlab-runner6. 搭建 harbor7. 开发应用8. 配置 BuildKit8.1 Registry mirror8.2 设置镜像仓库正式 9. 编写 .gitlabs-ci.yaml 1. 预…

5月更新,docsify综合漏洞知识库!

项目介绍 一个知识库&#xff0c;集成了Vulhub、Peiqi、EdgeSecurity、0sec、Wooyun等开源漏洞库&#xff0c;涵盖OA、CMS、开发框架、网络设备、开发语言、操作系统、Web应用、Web服务器、应用服务器等多种漏洞。 关注【Hack分享吧】公众号&#xff0c;回复关键字【230428】获…

深度探讨大模型位置编码及其外推性

深度探讨大模型位置编码及其外推性 作者&#xff1a;王嘉宁&#xff0c;转载请注明出处&#xff1a;https://wjn1996.blog.csdn.net/article/details/120607050 现如今很多大模型都开始支持超过4096长度的推理&#xff0c;例如GPT-4支持超过30k&#xff0c;ChatGLM2-6B也支持最…

mysql数据库-----事务

目录 1.事务的概念 2. 事务的ACID特点 &#xff08;1&#xff09;脏读 &#xff08;2&#xff09;不可重复读 &#xff08;3&#xff09;幻读 &#xff08;4&#xff09; 丢失更新 1.事务的概念 MySQL 事务主要用于处理操作量大&#xff0c;复杂度高的数据。比如说&…