【SpringMVC】异常处理

本文介绍了SpringMVC中异常处理的几种方式,包括基本介绍、局部异常处理、全局异常处理、自定义异常和统一处理异常。通过示例代码展示了如何使用@ExceptionHandler注解进行异常捕获,并解释了异常处理的优先级。此外,还提到了SimpleMappingExceptionResolver在统一处理异常中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录
一、基本介绍
二、局部异常
三、全局异常
四、自定义异常
五、统一处理异常
六、异常处理流程


相关文章(可以关注我的SpringMVC专栏)

SpingMVC专栏SpingMVC专栏

一、基本介绍

 如果我们对异常不做任何处理的话,那么他就会返回500错误,直接回显到前端页面,如下图:
在这里插入图片描述
这种提示方式无疑是很不友好的,所以SpringMVC提供了一种异常处理方式:

  1. Spring MVC 通过HandlerExceptionResolver处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。
  2. 主要处理 Handler 中用@ExceptionHandler注解定义的方法。
  3. ExceptionHandlerMethodResolver内部若找不到@ExceptionHandler注解的话,会找@ControllerAdvice类的@ExceptionHandler注解方法, 这样就相当于一个全局异常处理器。

二、局部异常

 局部异常处理就是只会处理当前Handler里边出现的异常。

前端

<%--
  Created by IntelliJ IDEA.
  User: huawei
  Date: 2022/12/1
  Time: 11:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试异常类</title>
</head>
<body>
<h1>测试异常类</h1>
<a href="<%=request.getContextPath()%>/testException01?num=0">测试局部异常处理</a>
</body>
</html>

后端

package com.jl.web.exception;

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

import javax.servlet.http.HttpServletRequest;

/**
 * ClassName: MyExceptionHandler
 * Package: com.jl.web.exception
 * Description: SpringMVC异常处理演示
 *
 * @Author: Long
 * @Create: 2022/12/1 - 11:07
 * @Version: v1.0
 */
@Controller
public class MyExceptionHandler {
    /**
     * 编写方法,模拟一场。
     * 如果我们不处理异常,模拟的是Tomcat来处理,页面不友好
     * 所以需要我们来处理异常
     * @param num
     * @return
     */
    @RequestMapping(value = "/testException01")
    public String test(Integer num){
        int i = 9/num;
        return "success";
    }

    /**
     * 该方法用来处理局部异常的
     * Exception exception: 生成的异常会传递给我们的exception对象
     * @return
     */
    @ExceptionHandler({ArithmeticException.class,NullPointerException.class,AgeException.class})
    public String test01(Exception exception, HttpServletRequest request){
        System.out.println("异常信息是:" + exception.getMessage());
        // 将异常携带到下一个页面
        request.setAttribute("reason",exception.getMessage());
        return "exception_msg";
    }
}

测试结果

在这里插入图片描述
这种错误回显效果明显更加的友好。

三、全局异常

前端

<%--
  Created by IntelliJ IDEA.
  User: huawei
  Date: 2022/12/1
  Time: 11:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试异常类</title>
</head>
<body>
<h1>测试异常类</h1>
<a href="<%=request.getContextPath()%>/testGlobalException">测试全局异常处理</a>
</body>
</html>

后端

package com.jl.web.exception;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;

/**
 * ClassName: MyGlobalException
 * Package: com.jl.web.exception
 * Description: 全局异常处理的演示
 *
 * @Author: Long
 * @Create: 2022/12/1 - 11:28
 * @Version: v1.0
 */

/**
 * 如果一个类上标注了 @ControllerAdvice ,那这个类就是一个全局异常处理类
 */
@ControllerAdvice
public class MyGlobalException {
    /**
     * 全局异常是:不管你是Handler抛出的异常,他都会去捕获处理
     * @return
     */
    @ExceptionHandler({NumberFormatException.class,ClassCastException.class})
    public String globalException(Exception exception, HttpServletRequest request){
        System.out.println("全局异常处理:" + exception);
        request.setAttribute("reason",exception.getMessage());
        return "exception_msg";
    }
}
package com.jl.web.exception;

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

import javax.servlet.http.HttpServletRequest;

/**
 * ClassName: MyExceptionHandler
 * Package: com.jl.web.exception
 * Description: SpringMVC异常处理演示
 *
 * @Author: Long
 * @Create: 2022/12/1 - 11:07
 * @Version: v1.0
 */
@Controller
public class MyExceptionHandler {
    /**
     * 编写方法,模拟一场。
     * 如果我们不处理异常,模拟的是Tomcat来处理,页面不友好
     * 所以需要我们来处理异常
     * @param num
     * @return
     */
    @RequestMapping(value = "/testException01")
    public String test(Integer num){
        int i = 9/num;
        return "success";
    }

    // 测试全局异常
    @RequestMapping(value = "/testGlobalException")
    public String global(){
        // 模拟抛出NumberFormatException异常
        // 该异常没有在局部异常处理,他就会交给全局异常处理。
        int num = Integer.parseInt("hello");
        return "success";
    }
}

测试结果

在这里插入图片描述

错误跳转页面

<%--
  Created by IntelliJ IDEA.
  User: huawei
  Date: 2022/12/1
  Time: 16:50
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>数值越界异常处理页面</title>
</head>
<body>
<h1>抱歉。数组越界异常</h1>
</body>
</html>

四、自定义异常

前端

<%--
  Created by IntelliJ IDEA.
  User: huawei
  Date: 2022/12/1
  Time: 11:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试异常类</title>
</head>
<body>
<h1>测试异常类</h1>
<a href="<%=request.getContextPath()%>/testException02">测试自定义异常处理</a>
</body>
</html>

后端

package com.jl.web.exception;

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

/**
 * ClassName: AgeException
 * Package: com.jl.web.exception
 * Description: 自定义异常类
 *
 * @Author: Long
 * @Create: 2022/12/1 - 11:54
 * @Version: v1.0
 */

/**
 * reason是我们返回错误页面,默认显示的信息。
 * value 是返回的状态码
 */
@ResponseStatus(reason = "年龄需要在1-150之间", value = HttpStatus.BAD_GATEWAY)
public class AgeException extends Exception{
    public AgeException() {
    }

    public AgeException(String message) {
        super(message);
    }
}
package com.jl.web.exception;

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

import javax.servlet.http.HttpServletRequest;

/**
 * ClassName: MyExceptionHandler
 * Package: com.jl.web.exception
 * Description: SpringMVC异常处理演示
 *
 * @Author: Long
 * @Create: 2022/12/1 - 11:07
 * @Version: v1.0
 */
@Controller
public class MyExceptionHandler {
    /**
     * 编写方法,模拟一场。
     * 如果我们不处理异常,模拟的是Tomcat来处理,页面不友好
     * 所以需要我们来处理异常
     * @param num
     * @return
     */
    @RequestMapping(value = "/testException01")
    public String test(Integer num){
        int i = 9/num;
        return "success";
    }

    // 测试自定义异常
    @RequestMapping(value = "/testException02")
    public String test02() throws AgeException {
        throw new AgeException("年龄必须要在1-150之间");
    }
}

测试结果

在这里插入图片描述

五、统一处理异常

 这种异常处理方式,是我们需要对所有异常进行统一处理的时候,可以使用SimpleMappingExceptionResolver。它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。这种方式需要在SpringMVC配置文件中进行配置。

<!--
   配置统一异常处理类
   1. SimpleMappingExceptionResolver 异常解析器
   2. key="java.lang.ArrayIndexOutOfBoundsException" 异常类
   3. arrEx:指定的处理异常之后跳转的页面
   4. <prop key="java.lang.Exception">arrEx</prop> 我们可以使用Exception来捕获未知的异常
   5. 异常的处理顺序:局部异常 > 全局异常 > SimpleMappingExceptionResolver > Tomcat默认的异常处理
-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
   <property name="exceptionMappings">
       <props>
           <prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop>
           <prop key="java.lang.Exception">arrEx</prop>
       </props>
   </property>
</bean>

前端

<%--
  Created by IntelliJ IDEA.
  User: huawei
  Date: 2022/12/1
  Time: 11:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试异常类</title>
</head>
<body>
<h1>测试异常类</h1>
<a href="<%=request.getContextPath()%>/testException03">测试统一异常处理</a>
</body>
</html>

后端

package com.jl.web.exception;

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

import javax.servlet.http.HttpServletRequest;

/**
 * ClassName: MyExceptionHandler
 * Package: com.jl.web.exception
 * Description: SpringMVC异常处理演示
 *
 * @Author: Long
 * @Create: 2022/12/1 - 11:07
 * @Version: v1.0
 */
@Controller
public class MyExceptionHandler {
    /**
     * 编写方法,模拟一场。
     * 如果我们不处理异常,模拟的是Tomcat来处理,页面不友好
     * 所以需要我们来处理异常
     * @param num
     * @return
     */
    @RequestMapping(value = "/testException01")
    public String test(Integer num){
        int i = 9/num;
        return "success";
    }

    // 统一处理异常测试
    @RequestMapping(value = "/testException03")
    public String test03(){
        int[] nums = new int[]{1,2,3};
        System.out.println(nums[5]);
        return "success";
    }
}

测试结果

在这里插入图片描述

 异常处理的优先级:
局部异常 > 全局异常 > SimpleMappingExceptionResolver > tomcat 默认机制

六、异常处理流程

在这里插入图片描述

如果文章中有描述不准确或者错误的地方,还望指正。您可以留言📫或者私信我。🙏
最后希望大家多多 关注+点赞+收藏^_^,你们的鼓励是我不断前进的动力!!!
感谢感谢~~~🙏🙏🙏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艺术留白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值