Spring源码学习(拓展篇):SpringMVC中的异常处理

目录

  • 前言
  • SimpleMappingExceptionResolver
  • [通过接口 HandlerExceptionResolver 实现](#通过接口 HandlerExceptionResolver 实现)
  • [通过 @ExpceptionHander+ @ControllerAdvice 注解实现(推荐)](#通过 @ExpceptionHander+ @ControllerAdvice 注解实现(推荐))

前言

SpringMVC的异常处理主要有以下三种方式:

  • 使用SpringMVC自带的异常处理类:SimpleMappingExceptionResolver
  • 自定义异常处理类:实现HandlerExceptionResolver接口
  • 使用注解:@ExpceptionHander+ @ControllerAdvice

SimpleMappingExceptionResolver

SimpleMappingExceptionResolver 异常处理器是 SpringMVC 定义好的异常处理器,具有以下特点。

  • 优点:集成简单、有良好的扩展性、对已有代码没有入侵性等
  • 缺点:该方法仅能获取到异常信息,对需要获取除异常以外的数据的情况不适用

在 SpingMVC 的配置文件中配置 SimpleMappingExceptionResolver 异常处理器

xml 复制代码
<!-- 配置异常映射 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="exceptionResolver">
    <!-- exceptionAttribute属性:设置将异常对象存入请求域时使用的属性名,默认使用"exception"作为属性名 -->
    <property name="exceptionAttribute" value="exception"></property>
    <!-- 用于指定具体的不同类型的异常所对应的异常响应页面。 -->
    <property name="exceptionMappings">
        <props>
            <!-- key属性:指定异常类型 -->
            <!-- 文本标签体:指定和异常对应的逻辑视图名称 -->
            <!-- 根据异常类型进行精确匹配,子类异常类型不匹配,才匹配父类异常类型 -->
            <prop key="java.lang.ArithmeticException">show-message</prop>
            <prop key="java.lang.RuntimeException">show-runtime-message</prop>
            <prop key="java.lang.Exception">show-exception-message</prop>
        </props>
    </property>
    <!-- 指定默认的异常响应页面。若发生的异常不是exceptionMappings中指定的异常,则使用默认异常响应页面。 -->
    <property name="defaultErrorView" value="error"></property>
</bean>

JSP中获取异常信息如下:

jsp 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>异常信息页面</title>
    </head>
    <body>
        <h1>系统信息</h1>
        异常对象:${requestScope.exception}<br/>
        异常消息:${requestScope.exception.message}<br/>
    </body>
</html>

通过接口 HandlerExceptionResolver 实现

自定义异常处理器类

java 复制代码
public class TestExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                                         Exception ex) {
        // 处理异常的逻辑
        // 可以设置错误视图、返回错误代码、记录异常信息等
        ModelAndView modelAndView = new ModelAndView("show-message");
        modelAndView.addObject("exception", ex);
        return modelAndView;
    }
}

在 SpringMVC 配置文件中配置异常处理器

java 复制代码
<bean class="com.changjunkai.config.TestExceptionHandler"></bean>

其实最后效果和上面的没啥区别,也是把异常对象给放到了域里

通过 @ExpceptionHander+ @ControllerAdvice 注解实现(推荐)

@ControllerAdvice 注解是 Spring Framework 中的一个注解,用于标识一个类为全局的控制器 advice (控制器增强)。
使用 @ControllerAdvice 注解的类可以提供以下功能:

  • 全局异常处理:可以使用 @ExceptionHandler 注解在 @ControllerAdvice 类中定义异常处理方法,以处理控制器中抛出的异常。这些方法可以捕获特定的异常类型,并返回相应的响应,如错误页面或错误信息
  • 全局数据验证:可以使用 @InitBinder 注解在 @ControllerAdvice 类中定义数据绑定初始化方法,以在请求处理之前对参数进行验证或自定义数据绑定规则
  • 全局拦截器:可以使用 @Interceptor 注解在 @ControllerAdvice 类中定义拦截器方法,以拦截所有控制器方法的调用,并在调用之前或之后执行额外的操作,如日志记录、权限检查等
  • 统一响应处理 :可以使用 @ResponseBody 注解在 @ControllerAdvice 类中定义响应处理方法,以统一处理控制器方法的返回值,并将其转换为合适的响应格式,如 JSON 或 HTML (@RestControllerAdvice注解就相当于@ControllerAdvice+@ResponseBody)

PS:使用 @ExceptionHandler 注解在 @Controller 类中定义的异常处理方法,只能作用于该类,无法处理全局异常。

java 复制代码
// 这个注解表示当前类是一个异常映射类
@ControllerAdvice
public class MyException {
 
    // 在@ExceptionHandler注解中指定异常类型
    @ExceptionHandler(value = {RuntimeException.class, ArithmeticException.class})
    public ModelAndView exceptionMapping(Exception exception) {// 方法形参位置接收SpringMVC捕获到的异常对象
 
        // 可以将异常对象存入模型;将展示异常信息的视图设置为逻辑视图名称
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("exception", exception);
        modelAndView.setViewName("show-message");
        // 打印一下信息
        System.out.println(exception.getMessage());
        return modelAndView;
    }
}

如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎各位大佬指正

相关推荐
奕澄羽邦2 分钟前
二级Python通关秘籍:字符串操作符/函数/方法全解析与实战演练
开发语言·python
Spring小子13 分钟前
蓝桥杯[每日两题] 真题:好数 神奇闹钟 (java版)
java·数据结构·算法·蓝桥杯
Ιτ-ωoгκεг17 分钟前
在 Java 中使用 Apache POI 为 Word 文档添加水印
java·word·apache·poi·水印
2302_7995257426 分钟前
【Hadoop】如何理解MapReduce?
数据库·hadoop·mapreduce
已是上好佳29 分钟前
介绍一下Qt中的事件过滤
java·服务器·数据库
Moonnnn.32 分钟前
51单片机——汇编工程建立、仿真、调试全过程
汇编·笔记·嵌入式硬件·学习·51单片机
go546315846533 分钟前
简单的 Python 示例,用于生成电影解说视频的第一人称独白解说文案
开发语言·python
vvilkim37 分钟前
使用 JavaScript 和 HTML5 实现强大的表单验证
开发语言·javascript·html5
Java中文社群38 分钟前
面试官:你项目是如何保证高可用的?
java·后端·面试
不修×蝙蝠44 分钟前
SpringBoot(一)--搭建架构5种方法
java·spring boot·架构·配置·搭建