首页 > 编程学习 > Spring mvc处理异常

Spring mvc处理异常

发布时间:2022/11/6 23:26:26

文章目录

    • 一、Handler ExceptionResolver处理异常
    • 二、@ExceptionHandler注解
    • 三、重点:添加@ExceptionHandler注解方法的形参只能是异常类型
    • 四、重点2:捕获所有方法的异常—@ControllerAdvice注解
    • 五、总结
    • 六、ResponseStatusExceptionResolve自定义异常显示页面
    • 七、扩展@ResponseStatus 用法
    • 八、其他异常处理
      • 8.1 DefaultHandlerExceptionResolver
      • 8.2 SymbolMappingExceptionResolver

一、Handler ExceptionResolver处理异常

Spring mvc处理异常的是顶级接口Handler ExceptionResolver
看一下该接口的源码所在的包
在这里插入图片描述
在这里插入图片描述
可以看到HandlerExceptionResolver接口在spring-webmvc包下
来看一下这个接口的实现类
在这里插入图片描述
上面每一个实现类都对应一种异常的处理方式
,重点来看ExceptionHandlerExceptionResolver

二、@ExceptionHandler注解

在这里插入图片描述
ExceptionHandlerExceptionResolver主要提供了
@ExceptionHandler 注解
通过在方法上添加该注解来实现异常处理
在Controller层写个异常
在这里插入图片描述
如图所示,这行代码会报ArithmeticException算术异常,以前我们可以使用try catch来处理,现在把try catch注释掉,再写一个方法HandlerArithmeticException(),并使用注解的形式来捕获异常,如下

在这里插入图片描述
添加@ExceptionHandler注解的这个方法就可以捕获本类中的异常,想要捕获指定的异常,就在注解后面添加参数,
上面我添加的是算数异常ArithmeticException.class因此,当前的这个方法就可以捕获上面的算术异常。代码如下

public String testExceptionHandler(){
//try {
    System.out.println( 1/0 );
//}catch(ArithmeticException e) e
    return "success";
}
//该方法可以捕获本类中抛出的ArithmeticException异常
@ExceptionHandler({ArithmeticException.class})
public String handlerArithmeticException(ArithmeticException e){
    System.out.println(e);
    return "error";
}

下面再写一个数组越界异常:
ArrayIndexOutOfBoundsException
用同一个方法捕获,只要在@HandlerException注解后面追加要捕获的异常的类名就可以

public String testExceptionHandler2(){
     int[] nums = new int[2];
     System.out.println(nums[2]);//ArrayIndexOutOfBoundsException
     return "success";
 }
//该方法可以捕获本类中抛出的ArithmeticException异常以及ArrayIndexOutOfBoundsException异常
@ExceptionHandler({ArithmeticException.class,ArrayIndexOutOfBoundsException.class})
public String handlerArithmeticException(Exception e){
     System.out.println(e)
     return "error";
}

三、重点:添加@ExceptionHandler注解方法的形参只能是异常类型

在这里插入图片描述
上面的handlerArithmeticException()方法的形参不能包含其他的,只能包含Exception e这一个
,总结一下,就是有@ExceptionHandler注解的方法的形参只能是异常类型的,而且只能有这个。

异常类型🈯️Throwable及其子类

//该方法可以捕获本类中抛出的ArithmeticException异常
@ExceptionHandler({ArithmeticException.class,ArrayIndexOutofBounds.class})
public ModelAndView handlerArithmeticException(Exception e){
   ModelAndView mv = new ModelAndView("error");//设置跳转的路径,error.jsp页面,前端调度器会自动添加"/",".jsp"
   System.out.println(e):
   mv.addobject("er", e);
   return mv;
}

上面的方法使用ModelAndView做跳转

四、重点2:捕获所有方法的异常—@ControllerAdvice注解

@ExceptionHandler注解默认只能处理本类中的异常,但是在实际应用中,发生异常的方法和处理异常的方法不会在同一个类中。
我们需要写一个单独用来处理异常的类
例如:MyExceptionHandler类
添加@ControllerAdvice注解,添加该注解的类,可以捕获所有方法的异常

import org.springframework.Web.bind.annotation.ControlierAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class MyExceptionHandler{
//不是控制器,仅仅是用于处理异常的类
@ExceptionHandler({Exception.class })
public ModelAndView handlerArithmeticException2(Exception e){
   ModelAndView mv = new ModelAndView("error");
   System.out.println(e+"a====="+"该@ControllerAdvice中的异常处理方法")
   mv.addobject("er", e);
   return mv;
}

五、总结

如果是只处理当前类方法中的异常,那就在使用@ExceptionHandler注解
在这里插入图片描述

如果想处理所有方法的异常,要在类前面加@ControllerAdvice,并且在处理异常的类前
添加@ExceptionHandler
在这里插入图片描述

六、ResponseStatusExceptionResolve自定义异常显示页面

我们平常异常页面404如图在这里插入图片描述
现在来自定义该页面:
通过ResponseStatusExceptionResolver类,
该类主要提供了@ResponseStatus注解,通过在类上面添加注解来定义异常处理页面,源码如下:
在这里插入图片描述
@ResponseStatus注解使用如下
在自定义的类MyArrayIndexOutofBoundsException上添加
在这里插入图片描述
填写value值先来了解HttpStatus,源码如下,可以看到是枚举类型
在这里插入图片描述
下面是HttpStatus部分定义:
在这里插入图片描述
403是页面禁止访问:Forbidden
404是找不到:Not Found
返回MyArrayIndexOutofBoundsException类来写一个403
在这里插入图片描述
可以写value值等于403也可以用HttpStatus.FORBIDDEN
在这里插入图片描述
上面两种写法意义相同

接下来定义reason,如果有方法的抛出异常MyArrayIndexOutofBoundsException,则报403错误,中文显示就是reason定义的内容:数组越界222!!!
在这里插入图片描述
最后一步
当前自定义的类继承Exception类
在这里插入图片描述
现在自定义的异常处理页面就写好了就写好了^O^/

定义一个会报异常的的方法,测试一下,刚刚自定义的异常处理页面
在这里插入图片描述
如果前端发来的请求中i=3,就抛出异常
MyArrayIndexOutofBoundsException
tomcat运行,访问上面那个方法,请求路径上传参用?连接i=3

在这里插入图片描述
运行结果:可以看到自定义定义的reason:数组越界222!!!在这里插入图片描述

七、扩展@ResponseStatus 用法

定义testMyException2()方法
如果前端传来的值i=3
return “testResponseStatus”;
该返回值直接请求当前类中定义的另一个方法testResponseStatus(),注意是请求当前类中的方法!!且该方法:@RequestMapping(“testResponseStatus”),与上面返回值对应
如下图示:
在这里插入图片描述
我们在testResponseStatus()方法上面添加注解@ResponseStatute
在这里插入图片描述
完整代码如上,现在运行测试,
访问/testMyException2?i=3
在这里插入图片描述
运行报错,没有找到textResponseStatus.jsp页面 在这里插入图片描述
这里是因为前端调度器,会自动为返回值添加前缀“/”和后缀“.jsp”,
想要正确访问,需要使用redirect跳转
如下图所示
在这里插入图片描述
Springmvc传值和跳转可以看这篇:
Spring mvc传值和跳转

@RequestMapping("testMyException2")
public String testMyException2(@RequestParam("i") Integeri){
    if(i == 3){
      return "redirect:testResponseStatus”;//跳转到某一个异常处理方法里
      return "success";
}
@ResponseStatus(value=HttpStatus.COWFLICT ,reason="测试。。。”)
@RequestMapping("testResponseStatus")
public String testResponseStatus(){
    return "success";

再次运行访问路径
/testMyException2?i=3
运行结果如下:
在这里插入图片描述
异常页面和定义的一致
在这里插入图片描述
总结:
@ResponseStatus注解可以写在方法前,也可以写在类前。

异常解析:Spring mvc异常解析器与拦截器

八、其他异常处理

8.1 DefaultHandlerExceptionResolver

也是Spring mvc处理异常的是顶级接口Handler ExceptionResolver的实现类
在这里插入图片描述
这是一个默认处理
就是你不用写,如果有报错,会默认跳转到异常处理页面,如下所示
在这里插入图片描述
现在来浏览器输入
localhost:8888/SpringMVCProject/handler/welcome2
(又重新写了一个welcome5方法,所以下面截图中访问的是方法5)
在这里插入图片描述
可以看到异常显示页面405。

异常处理的实现类:
DefaultHandlerExceptionResolver
SPringMVC在常见异常的基础上(300 500 404),新增了一些异常,例如405—Method not Allowed,
部分源码如下:

在这里插入图片描述

*@see org. springframework. weh. servlet. mvc. method. annotation. ResponseEntityExceptioniandler
*@see #handleNoSuchRequestHandlingMethod
*@see #handleHttpRequestMethodNotSupported
*@see #handleHttpMediaTypeNotSupported
*@see #handleMissingServletRequestParameter
*@see #handleServletRequestBindingException
*@see #handleTypeMismatch
*@see #handleHttpMessageNotReadable
*@see #handleHttpMessageNotWritable
*@see #handleMethodArgumentNotValidException
*@see #handleMissingServletRequestParameter
*@see #handleMissingServletRequestPartException
*@see #handleBindException

8.2 SymbolMappingExceptionResolver

也是Spring mvc处理异常的是顶级接口Handler ExceptionResolver的实现类
在这里插入图片描述
SymbolMappingExceptionResolver通过配置实现处理异常

在这里插入图片描述
在这里插入图片描述

<!-- SimpleMappingExceptionResolver:以配置的方式处理异常-->
<bean class="org.springframework.web.servlet.handler.SimpleMappinge">
   <property name="exceptionMappings">
        <props>
            <!--相当于catch(ArithmeticException e){ 跳转:error.jsp-->
            <prop key="java.lang.ArithmeticException">
               error
            </prop>
        </props>
    </property>
</bean>

props标签中可以添加多个prop,再写一个空指针异常,如果异常,就跳转到error.jsp

<!-- SimpleMappingExceptionResolver:以配置的方式处理异常-->

<bean class="org.springframework.web.servlet.handler. SimpleMappingException">
     <property name="exceptionAttribute" value="ex"></property>
     <property name="exceptionMappings">
         <props>
             <!--相当于catch(ArithmeticException ex){跳转:error}--> 
             <prop key="java.lang.ArithmeticException">
                 error
             </prop>
             <prop key="java.lang.NullPointerException">
                 error
             </prop>
         </props>
     </property>
</bean>

以下代码,如果捕获到异常会,异常对象会保存在exceptionAttribute的value值:ex中,并且会被放到request作用域中

<property name="exceptionAttribute" value="ex"></property>

不管捕获到的是算数异常或空指针异常,都可以通过${requestScope.ex}取值
在这里插入图片描述
以下error.jsp页面代码

<%@ page language="jdva" contentType="text/html; charset=UTF-8'
pageEncoding="UTF-8"%>
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
   <title>Insert title here</title>
</head>
<body>
    error.jsp..<br/>
    ${requestScope.ex}
</body>

</html>

如果不写这行代码

<property name="exceptionAttribute" value="ex"></property>

也可以,默认exceptionAttribute的value值是exception
可以通过
${requestScope.exception}取值

tomcat运行,访问下面这个方法的算术异常在这里插入图片描述
结果如下,跳转到error.jsp页面
在这里插入图片描述
通过${requestScope.exception}取值—>算术异常

Copyright © 2010-2022 dgrt.cn 版权所有 |关于我们| 联系方式