Spring MVC异常处理

在 Spring MVC 应用的开发中,不管是操作底层数据库,还是业务层或控制层,都会不可避免地遇到各种可预知的、不可预知的异常。我们需要捕捉处理异常,才能保证程序不被终止。

 

一种是使用HandlerExceptionResolver接口;一种是在Controller类内部使用@ExceptionHandler注解。使用第一种方式可以实现全局异常控制,并且Spring已经提供了一个默认的实现类SimpleMappingExceptionResolver;使用第二种方式可以在Controller内部实现更个性化点异常处理方式,灵活性更高。一般来说,项目中只需要采用第一种方式就可以了,每个人都自己定义异常的展现方式,太过个性了,不统一。


Spring MVC 有以下 3 种处理异常的方式:

  1. 使用 Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver
  2. 实现 Spring 的异常处理接口 HandlerExceptionResolver,自定义自己的异常处理器。
  3. 使用 @ExceptionHandler 注解实现异常处理。

1. @ExceptionHandler

 

该方法需要定义在Controller内部,然后创建一个方法并用@ExceptionHandler注解来修饰用来处理异常,@ExceptionHandler中可以添加一个或多个异常的类型,如果为空的话则认为可以触发所有的异常类型错误。ref:https://blog.csdn.net/rj042/article/details/7380442

局部异常处理仅能处理指定 Controller 中的异常。

示例 1:下面使用 @ExceptionHandler 注解实现。定义一个处理过程中可能会存在异常情况的 testExceptionHandle 方法。

@RequestMapping("/testExceptionHandle")
public String testExceptionHandle(@RequestParam("i") Integer i) {
    System.out.println(10 / i);
    return "success";
}

 

显然,当 i=0 时会产生算术运算异常。

下面在同一个类中定义处理异常的方法。

@ExceptionHandler({ ArithmeticException.class })
public String testArithmeticException(Exception e) {
    System.out.println("打印错误信息 ===> ArithmeticException:" + e);
    // 跳转到指定页面
    return "error";
}

 

注意:该注解不是加在产生异常的方法上,而是加在处理异常的方法上。

异常页面 error.jsp 代码如下。

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>错误页面</title>
</head>
<body>
    发生算术运算异常,请重新输出数据!
</body>
</html>
复制代码

 

访问地址:http://localhost:8080/springmvcDemo2/testExceptionHandle?i=0,页面跳转到 error.jsp 页面,运行结果如图 1 所示。

error.jsp页面
图 1:error.jsp页面

控制器输出结果如下。

打印错误信息 ===> ArithmeticException:java.lang.ArithmeticException: / by zero

 

@ExceptionHandler 注解定义的方法优先级问题:例如发生的是 NullPointerException,但是声明的异常有 RuntimeException 和 Exception,这时候会根据异常的最近继承关系找到继承深度最浅的那个@ExceptionHandler 注解方法,即标记了 RuntimeException 的方法。

被 @ExceptionHandler 标记为异常处理方法,不能在方法中设置别的形参。但是可以使用 ModelAndView 向前台传递数据。

使用局部异常处理,仅能处理某个 Controller 中的异常,若需要对所有异常进行统一处理,可使用以下两种方法。

 

2. HandlerExceptionResolver

Spring MVC 通过 HandlerExceptionResolver 处理程序异常,包括处理器异常、数据绑定异常以及控制器执行时发生的异常。HandlerExceptionResolver 仅有一个接口方法,源码如下。

public interface HandlerExceptionResolver {
    @Nullable
    ModelAndView resolveException(
            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}

 

发生异常时,Spring MVC 会调用 resolveException() 方法,并转到 ModelAndView 对应的视图中,返回一个异常报告页面反馈给用户。

示例 2:在 net.biancheng.exception 包中创建一个 HandlerExceptionResolver 接口的实现类 MyExceptionHandler,代码如下。

复制代码
package net.biancheng.exception;

import java.util.HashMap;
import java.util.Map;

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

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

public class MyExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
            Exception arg3) {
        Map<String, Object> model = new HashMap<String, Object>();
        // 根据不同错误转向不同页面(统一处理),即异常与View的对应关系
        if (arg3 instanceof ArithmeticException) {
            return new ModelAndView("error", model);
        }
        return new ModelAndView("error-2", model);
    }
}
复制代码

 

在 springmvc-servlet.xml 文件中添加以下代码。

<!--托管MyExceptionHandler-->
<bean class="net.biancheng.exception.MyExceptionHandler"/>

 

再次访问 http://localhost:8080/springmvcDemo2/testExceptionHandle?i=0,页面跳转到 error.jsp 页面,运行结果如上图 1 所示。

 

3. SimpleMappingExceptionResolver

全局异常处理可使用 SimpleMappingExceptionResolver 来实现。它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。

示例 3:在 springmvc-servlet.xml 中配置全局异常,代码如下。

复制代码
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 定义默认的异常处理页面,当该异常类型注册时使用 -->
    <property name="defaultErrorView" value="error"></property>
    <!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
    <property name="exceptionAttribute" value="ex"></property>
    <!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值 -->
    <property name="exceptionMappings">
        <props>
            <prop key="ArithmeticException">error</prop>
            <!-- 在这里还可以继续扩展对不同异常类型的处理 -->
        </props>
    </property>
</bean>
复制代码

 

再次访问 http://localhost:8080/springmvcDemo2/testExceptionHandle?i=0,页面跳转到 error.jsp 页面,运行结果如上图 1 所示。

 

From

http://c.biancheng.net/spring_mvc/exception.html

posted @   emanlee  阅读(152)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2019-08-16 为Endnote中的期刊名称添加缩写期刊名
2017-08-16 qvalue: Check that you have valid p-values or use a different range of lambda
2014-08-16 mysql 字符串函数
2011-08-16 WinRAR命令行参数
2011-08-16 水平集方法 level set method
2011-08-16 基底膜(basement membrane, BM)
2011-08-16 肿瘤基础知识
点击右上角即可分享
微信分享提示