当前位置: 首页 > article >正文

Spring MVC 之 异常处理

使用Spring MVC可以很灵活地完成数据的绑定和响应,极大的简化了Java Web的开发。但Spring MVC提供的便利不仅仅如此,使用Spring MVC还可以很便捷地完成项目中的异常处理、自定义拦截器以及文件上传和下载等高级功能。本章将对Spring MVC提供的这些高级功能进行讲解。

异常处理

简单异常处理器

如果希望对Spring MVC中所有异常进行统一处理,可以使用Spring MVC提供的异常处理器HandlerExceptionResolver接口。

Spring MVC内部提供了HandlerExceptionResolver的实现类SimpleMappingExceptionResolver。它实现了简单的异常处理,通过该实现类可以将不同类型的异常映射到不同的页面,当发生异常的时候,实现类根据发生的异常类型跳转到指定的页面处理异常信息。实现类也可以为所有的异常指定一个默认的异常处理页面,当应用程序抛出的异常没有对应的映射页面,则使用默认页面处理异常信息。

案例演示

下面通过一个案例演示SimpleMappingExceptionResolver对异常的统一处理,案例具体实现步骤如下所示。

package com.lq.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Objects;/*** @Author: Luqing Teacher* @CreateTime: 2025-03-13* @Description: ExceptionController* @Version: 1.0*/@Controller
public class ExceptionController {// 抛出空指针异常@RequestMapping("/showNullPointer")public void showNullPointer(){ArrayList<Object> list = new ArrayList<>();System.out.println(list.get(2));}// 抛出IO异常@RequestMapping("/showIOException")public void showIOException() throws FileNotFoundException {FileInputStream in = new FileInputStream("javaweb.xml");}// 抛出算术异常@RequestMapping("/showArithmetic")public void showArithmetic(){int a = 1/0;}
}

程序执行文件ExceptionController.java中的任意一个方法时,都会抛出异常。在异常发生时,如果要跳转到指定的处理页面,则需要在Spring MVC的配置文件spring-mvc.xml中使用SimpleMappingExceptionResolver指定异常和异常处理页面的映射关系。Spring MVC配置文件的部分配置如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 配置 Spring MVC 要扫描的包 --><context:component-scan base-package="com.lq.controller"/><!-- 配置视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/></bean><!-- 配置注解驱动 --><mvc:annotation-driven /><!--配置静态资源的访问映射,此配置中的文件,将不被前端控制器拦截 --><mvc:resources mapping="/js/**" location="/js/" /><!-- 注入 SimpleMappingExceptionResolver 异常处理器--><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><!-- 定义特殊处理的异常,类名或完全路径名作为key,对应的异常页面名作为值--><property name="exceptionMappings"><props><prop key="java.lang.NullPointerException">nullPointerExp.jsp</prop><prop key="java.io.IOException">IOExp.jsp</prop></props></property><!-- 为所有异常定义默认的异常页面,value为默认的异常页面名--><property name="defaultErrorView" value="defaultExp.jsp"/><!-- value定义在异常处理页面中获取异常信息的变量名,默认为exception --><property name="exceptionAttribute" value="exp"/></bean>
</beans>

在文件spring-mvc.xml中,已经指定了异常类别对应的异常处理页面,接下来创建这些异常处理页面。在此不对异常处理页面做太多处理,只在页面中展示对应的异常信息。

接下来在webapp下创建nullPointerExp.jsp、IOExp.jsp、defaultExp.jsp页面分别如下:(内容修改成指定的页面)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>空指针异常处理页面</title></head>
<body>
空指针异常处理页面-----${exp}
</body>
</html>

结果如下:

从图中所示的信息可以看出,程序在抛出异常时,会跳转到异常类型对应的异常处理页面中。如果抛出的异常没有在Spring MVC的配置文件中指定对应的异常处理页面,那么程序会跳转到指定的默认异常处理页面。

自定义异常处理器

resolveException()方法

除了使用SimpleMappingExceptionResolver进行异常处理,还可以自定义异常处理器统一处理异常。通过实现HandlerExceptionResolver接口,重写异常处理方法resolveException()来定义自定义异常处理器。当Handler执行并且抛出异常时,自定义异常处理器会拦截异常并执行重写的resolveException()方法,该方法返回值是ModelAndView类型的对象,可以在ModelAndView对象中存储异常信息,并跳转到异常处理页面。

案例演示

接下来通过一个案例演示自定义异常处理器分类别处理自定义异常和系统自带的异常,案例具体实现步骤如下所示。在src\main\java目录,创建一个路径为com.lq.exception的包,并在包中创建自定义异常类MyException:

package com.lq.exception;/*** @Author: Luqing Teacher* @CreateTime: 2025-03-13* @Description:* @Version: 1.0*/public class MyException extends Exception {private String message;//异常信息public MyException(String message) {super(message);this.message = message;}@Overridepublic String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}

在ExceptionController类中,新增方法addData()用于抛出自定义异常,addData()方法的具体代码如下所示

@RequestMapping("/addData")
public String addData() throws MyException {throw new MyException("新增数据异常!");
}

在com.lq.controller包下,创建名称为MyExceptionHandler的自定义异常处理器。在MyExceptionHandler类中重写resolveException()方法,用于判断当前异常是自定义异常还是系统自带的异常,根据异常的种类不同,resolveException()方法返回不同的异常信息。使用自定义异常处理器,需要先将自定义异常处理器注册到Spring MVC中。MyExceptionHandler类的部分代码如下所示。

package com.lq.controller;import com.lq.exception.MyException;
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;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;/*** @Author: Luqing Teacher* @CreateTime: 2025-03-13* @Description:* @Version: 1.0*/@Component
public class MyExceptionHandler implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {String msg;if(ex instanceof MyException) {msg = ex.getMessage();}else {Writer out = new StringWriter();PrintWriter s = new PrintWriter(out);ex.printStackTrace(s);String sysMsg = out.toString();msg = "<h1>你个傻冒,又出错了吧!!</h1>" + sysMsg;}ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("msg", msg);modelAndView.setViewName("error.jsp");return modelAndView;}
}

访问showNullPointer,出现下列页面

​访问addData

异常处理注解

@ControllerAdvice注解的作用

从Spring 3.2开始,Spring提供了一个新注解@ControllerAdvice,@ControllerAdvice有以下两个作用。

• 注解作用在类上时可以增强Controller,对Controller中被@RequestMapping注解标注的方法加一些逻辑处理。

• @ControllerAdvice注解结合方法型注解@ExceptionHandler,可以捕获Controller中抛出的指定类型的异常,从而实现不同类型的异常统一处理。

案例演示

接下来通过一个案例演示使用注解实现异常的分类处理,具体实现步骤如下所示。

在com.lq.controller包下,创建名称为ExceptionAdvice的异常处理器。ExceptionAdvice类中定义2个处理不同异常的方法,其中doMyException()方法用来处理Handler执行时抛出的自定义异常,doOtherException()方法用来处理Handler执行时抛出的系统异常。

package com.lq.controller;import com.lq.exception.MyException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;/*** @Author: Luqing Teacher* @CreateTime: 2025-03-13* @Description:* @Version: 1.0*/@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandler(value = MyException.class)public ModelAndView doMyException(Exception ex) {ModelAndView mv = new ModelAndView();mv.addObject("msg", ex.getMessage());mv.setViewName("error.jsp");return mv;}@ExceptionHandler(value = Exception.class)public ModelAndView doOtherException(Exception ex) {ModelAndView mv = new ModelAndView();mv.addObject("msg", "<h1>傻冒出错了吧!!哈哈!!</h1>");mv.setViewName("error.jsp");return mv;}}

相关文章:

Spring MVC 之 异常处理

使用Spring MVC可以很灵活地完成数据的绑定和响应&#xff0c;极大的简化了Java Web的开发。但Spring MVC提供的便利不仅仅如此&#xff0c;使用Spring MVC还可以很便捷地完成项目中的异常处理、自定义拦截器以及文件上传和下载等高级功能。本章将对Spring MVC提供的这些高级功…...

缓存控制HTTP标头设置为“无缓存、无存储、必须重新验证”

文章目录 说明示例核心响应头设置实现原理代码实现1. 原生 Node.js (使用 http 模块)2. Express 框架3. 针对特定路由设置 (Express) 验证方法&#xff08;使用 cURL&#xff09;关键注意事项 说明 日期&#xff1a;2025年6月4日。 对于安全内容&#xff0c;请确保缓存控制HT…...

ubuntu24.04 使用apt指令只下载不安装软件

比如我想下载net-tools工具包及其依赖包可以如下指令 apt --download-only install net-tools 自动下载的软件包在/var/cache/apt/archives/目录下...

macOS 上使用 Homebrew 安装redis-cli

在 macOS 上使用 Homebrew 安装 redis-cli&#xff08;Redis 命令行工具&#xff09;非常简单&#xff0c;以下是详细步骤&#xff1a; 1. 安装 Redis&#xff08;包含 redis-cli&#xff09; 运行以下命令安装 Redis&#xff1a; brew install redis这会安装完整的 Redis 服…...

计算机网络安全问答数据集(1788条) ,AI智能体知识库收集! AI大模型训练数据!

继续收集数据集&#xff0c;话不多说&#xff0c;见下文&#xff01; 今天分享一个计算机网络安全问答数据集&#xff08;1788条)&#xff0c;适用于AI大模型训练、智能体知识库构建、安全教育系统开发等多种场景&#xff01; 一、数据特点 结构清晰&#xff1a;共计1788条&…...

WinCC学习系列-高阶应用(WinCC REST通信)

WinCC作为一个经典SCADA系统&#xff0c;它是OT与IT数据无缝集成桥梁&#xff0c;自WinCC7.5版本开始&#xff0c;可以直接提供Rest服务用于其它系统数据访问和操作。 WinCC REST 服务允许外部应用程序访问 WinCC 数据。 外部应用程序可以通过 REST 接口读取和写入 WinCC 组态…...

八、Python模块、包

目录 1. 模块 1.1 什么是模块&#xff1f; 1.2 创建模块 1.3 导入模块 1.4 模块的命名空间 1.5 模块的搜索路径 1.6 模块的重新加载 2. 包 2.1 什么是包&#xff1f; 2.2 创建包 2.3 导入包中的模块 2.4 包的层次结构 3. 模块和包的管理 3.1 安装模块 3.2 卸载模…...

使用交叉编译工具提示stubs-32.h:7:11: fatal error: gnu/stubs-soft.h: 没有那个文件或目录的解决办法

0 前言 使用ST官方SDK提供的交叉编译工具、cmake生成Makefile&#xff0c;使用make命令生成可执行文件提示fatal error: gnu/stubs-soft.h: 没有那个文件或目录的解决办法&#xff0c;如下所示&#xff1a; 根据这一错误提示&#xff0c;按照网上的解决方案逐一尝试均以失败告…...

macOS 连接 Docker 运行 postgres,使用navicat添加并关联数据库

下载 docker注册一个账号&#xff0c;登录 Docker创建 docke r文件 mkdir -p ~/.docker && touch ~/.docker/daemon.json写入配置&#xff08;全量替换&#xff09; {"builder": {"gc": {"defaultKeepStorage": "20GB",&quo…...

指针的使用——基本数据类型、数组、结构体

1 引言 对于学习指针要弄清楚如下问题基本可以应付大部分的场景&#xff1a; ① 指针是什么&#xff1f; ② 指针的类型是什么&#xff1f; ③ 指针指向的类型是什么&#xff1f; ④ 指针指向了哪里&#xff1f; 2 如何使用指针 任何东西的学习最好可以总结成一种通用化的…...

TK海外抢单源码/指定卡单

​ 抢单源码&#xff0c;有指定派单&#xff0c;打针&#xff0c;这套二改过充值跳转客服 前端vue 后端php 两端分离 可二开 可以指定卡第几单&#xff0c;金额多少&#xff0c; 前后端开源 PHP7.2 MySQL5.6 前端要www.域名&#xff0c;后端要admin.域名 前端直接静态 伪静…...

Docker MCP 目录和工具包简介:使用 MCP 为 AI 代理提供支持的简单安全方法

目录 Model Context Protocol 势头强劲 — 还需要改进哪些?发现正确的、官方的和/或值得信赖的工具是很困难的复杂的安装和分发身份验证和权限不足Docker 如何帮助解决这些挑战在安全、隔离的容器中轻松发现和运行 MCP 服务器一键式 MCP 客户端集成,内置安全认证企业就绪的 M…...

【Linux】Linux 环境变量

参考博客&#xff1a;https://blog.csdn.net/sjsjnsjnn/article/details/125533127 一、环境变量 1.1 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&am…...

OpenCV在图像上绘制文字示例

OpenCV计算机视觉开发实践&#xff1a;基于Qt C - 商品搜索 - 京东 OpenCV中除了提供绘制各种图形的函数外&#xff0c;还提供了一个特殊的绘制函数&#xff0c;用于在图像上绘制文字。这个函数是putText()&#xff0c;它是命名空间cv中的函数&#xff0c;其声明如下&#xff…...

Java 抗量子算法:构建后量子时代的安全基石

一、量子计算带来的加密挑战 在传统加密体系中&#xff0c;RSA、ECC 等公钥算法依赖大数分解和离散对数问题的难解性。然而&#xff0c;量子计算机的 Shor 算法可在多项式时间内破解这些算法&#xff0c;使现有加密体系面临颠覆性威胁。例如&#xff0c;2048 位 RSA 密钥的破解…...

Kubernetes 集群到 Jumpserver

以下是使用 ServiceAccount Token&#xff08;令牌&#xff09; 连接 Kubernetes 集群到 Jumpserver 的 详细分步指南&#xff0c;包括权限配置、Token 获取和常见问题排查。 1. 创建 ServiceAccount 并分配权限 1.1 创建 ServiceAccount 在 Kubernetes 集群中创建一个专用于…...

Android7 Input(十)View 处理Input事件pipeline

概述: 本文主要描述View对InputEvent事件pipeline处理过程。 本文涉及的源码路径 frameworks/base/core/java/android/view/ViewRootImpl.java InputEvent事件处理 View处理input事件是调用doProcessInputEvents方法&#xff0c;如下所示: void doProcessInputEvents() {//…...

图像数据如何表示为概率单纯形

目录 图像数据灰度图像彩色图像概率单纯形条件应用场景 图像数据 图像数据通常由像素值组成&#xff0c;这些像素值可以是灰度值&#xff08;对于黑白图像&#xff09;或RGB值&#xff08;对于彩色图像&#xff09;。每个像素的值通常在0到255之间。为了将图像数据表示为概率单…...

(11)Service Mesh架构下Java应用实现零信任安全模型

Service Mesh架构下Java应用实现零信任安全模型 📌 TL;DR: 本文详细介绍如何在Service Mesh架构中实现零信任安全模型,包括身份认证、授权控制、加密通信和持续监控四大核心技术,以及与Istio、Envoy等组件的集成方案。 目录 零信任安全模型概述关键技术实现最佳实践Service…...

什么是内网映射?如何将内网ip映射到外网访问?

随着互联网科技和信息技术的快速发展&#xff0c;很多原理及技术开始被应用到互联网信息科技领域&#xff0c;其中内网iP映射就成为非常普通常见的一个操作。那么什么是内网ip映射&#xff1f;如何将内网ip映射到外网&#xff1f; 一、什么是内网ip映射&#xff1f; 简单理解…...

为什么要选择VR看房?VR看房有什么优点?

VR看房&#xff1a;革新传统&#xff0c;重塑体验 在当今社会&#xff0c;虚拟现实&#xff08;VR&#xff09;技术正以前所未有的速度渗透到我们生活的各个领域&#xff0c;其中VR看房作为房地产领域的重要创新。本文将讨论为什么要选择VR看房以及VR看房的主要优点&#xff0…...

linux 串口调试命令 stty

linux 串口调试命令 stty 文章目录 linux 串口调试命令 sttystty 常见命令选项&#xff1a;常用参数&#xff1a;一次性设置串口所有常见参数总结 stty&#xff08;设置终端行模式&#xff09;命令是用来配置终端设备&#xff08;包括串口设备&#xff09;的输入和输出行为的工…...

C++STL-vector的使用

vector的定义方式 方式1&#xff1a;构造某一个类型的空容器 vector<int> v1;//构造一个int类型的空容器 方式2&#xff1a;构造一个含有n个val的某类型容器 vector<int> v2(10, 2);//构造一个含有10个2的int类型的容器 方式3&#xff1a;拷贝构造某类型容器 …...

图简记。。

模仿&#xff1a; algorithm-journey/src/class059/Code01_CreateGraph.java at main algorithmzuo/algorithm-journey Code01_CreateGraph C语言&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>#define MAXN 11 #define MAX…...

pytorch基本运算-范数

引言 前序学习进程中&#xff0c;已经对pytorch基本运算有了详细探索&#xff0c;文章链接有&#xff1a; 基本运算 广播失效 乘除法和幂运算 hadamard积、点积和矩阵乘法 上述计算都是以pytorch张量为运算元素&#xff0c;这些张量基本上也集中在一维向量和二维矩阵&#x…...

uefi协议设计目的

在EDK2的术语体系中&#xff0c;GUID定义的是协议的标识符&#xff0c;而具体实现的函数集合称为协议的实现。它们是同一协议的不同抽象层次&#xff0c;以下是详细解释&#xff1a; 1. 协议&#xff08;Protocol&#xff09;的两层含义 (1) 协议规范&#xff08;接口定义&am…...

springcloud openfeign 偶现 Caused by: java.net.UnknownHostException

背景 最近查看日志发现某服务偶现Caused by: java.net.UnknownHostException 同时查看eureka的access.log 出现如下异常 10.xxx.xxx.xxx - - [27/May/2025:23:57:29 0800] “PUT /eureka/apps/{appName}/{host}:xxx-job:8082?statusUP&lastDirtyTimestamp1748351637173 H…...

Transformer实战——词嵌入技术详解

Transformer实战——词嵌入技术详解 0. 前言1. 词嵌入基础2. 分布式表示3. 静态嵌入3.1 Word2Vec3.2 GloVe 4. 使用 Gensim 构建词嵌入5. 使用 Gensim 探索嵌入空间6. 动态嵌入小结系列链接 0. 前言 在本节中&#xff0c;我们首先介绍词嵌入的概念&#xff0c;然后介绍两种实现…...

[pdf、epub]300道《软件方法》强化自测题业务建模需求分析共257页(202505更新)

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 在本账号CSDN资源下载&#xff0c;或者访问链接&#xff1a; http://www.umlchina.com/url/quizad.html 如果需要提取码&#xff1a;umlc 文件夹中的“300道软件方法强化自测题2025…...

Vue3入门指南:从零到精通的快速上手

齐爷学vue3 一、Vue3入门 vite&#xff1a;前端构架工具&#xff0c;构建速度快于webpack。轻量快速、对TS&#xff0c;JSX&#xff0c;CSS开箱即用、按需编译。 创建Vue3工程 1.在想要创建Vue3的位置打开cmd&#xff0c;执行如下命令。 npm create vuelatest 2.功能只选择…...