SpringMVC 学习笔记(7)异常操作
如何使用HandleException
在程序中,异常是最常见的,我们需要捕捉异常并处理它,才能保证程序不被终止。
最常见的异常处理方法就是用try catch来捕捉异常。这次我们使用springmvc给我们提供的方法来处理异常
先模拟一个异常出现的场景。以下是一个简单的数学异常
package com.ibigsea.springmvc.handler; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; @Controller
public class Exception2Handler { //注意,该注解不是加在产生异常的方法上,而是另外写一个方法
@ExceptionHandler({ArithmeticException.class})
public ModelAndView testArithmeticException(Exception e){
System.out.println("ArithmeticException:"+e);
//我们要将异常在error页面中进行显示,并且将异常信息带到页面上显示出来
//这里不能采用map的方式,@ExceptionHandler和map不能配合使用
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("exception", e);
return modelAndView;
} @RequestMapping("/testException")
public String testException(){
int i = 10 /0;
return "sucess";
} }
当i的值为0的时候,就会抛出数学异常。该如何捕捉呢,我们使用ExceptionHandler注解
- ExceptionHandler 的value属性是一个Class 数组,因此我们可以在该注解的属性中加入多个异常类
- 当目标方法产生异常时,将被这个方法捕捉,我们可以得到异常的实例
- 注意,捕捉异常的方法要和目标方法在同一个controller中
error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body>
错误信息:${exception } </body>
</html>
HandleException的优先级
当一个controller中有多个HandleException注解出现时,那么异常被哪个方法捕捉呢?这就存在一个优先级的问题
package com.ibigsea.springmvc.handler; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; @Controller
public class Exception2Handler { //注意,该注解不是加在产生异常的方法上,而是另外写一个方法
@ExceptionHandler({ArithmeticException.class})
public ModelAndView testArithmeticException(Exception e){
System.out.println("ArithmeticException:"+e);
//我们要将异常在error页面中进行显示,并且将异常信息带到页面上显示出来
//这里不能采用map的方式,@ExceptionHandler和map不能配合使用
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("exception", e);
return modelAndView;
} @ExceptionHandler({RuntimeException.class})
public String testRuntimeException(Exception e){
System.out.println("RuntimeException"+e);
return "error";
}
@RequestMapping("/testException")
public String testException(){
int i = 10 /0;
return "sucess";
} }
访问目标方法,让它抛异常,看控制台打印结果,发现它抛了ArithmeticException:java.lang.ArithmeticException: / by zero这个异常
因此我们可以确定,ExceptionHandler的优先级是:在异常的体系结构中,哪个异常与目标方法抛出的异常血缘关系越紧密,就会被哪个捕捉到。
捕捉全局的异常
ExceptionHandler只能捕捉同一个controller中的异常,其实我们也有办法捕捉整个程序中所有的异常
新建一个类,加上@ControllerAdvice注解
package com.ibigsea.springmvc.handler; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; //处理异常
@ControllerAdvice
public class HandleForException { @ExceptionHandler({ArithmeticException.class})
public String testArithmeticException(Exception e){
System.out.println("ArithmeticException:"+e);
return "error";
}
}
在这个类中使用ExceptionHandler,就能捕捉所有的controller中发生的异常
结论

52. 尚硅谷_佟刚_SpringMVC_异常处理_ResponseStatusExceptionResolver.avi
带有@ResponseStatus注解的异常类会被ResponseStatusExceptionResolver 解析。可以实现自定义的一些异常,同时在页面上进行显示。具体的使用方法如下:
1.首先定义一个异常类:
@ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用户名和密码不匹配!")
public class UserNameNotMatchPasswordException extends RuntimeException{ }
- ResponseStatus注解是修饰类的
- 它有两个属性,value属性是http状态码,比如404,500等。reason是错误信息
2.人为抛出一个异常:
@RequestMapping("/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if (i==13){
throw new UserNameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver....");
return "success";
}
3.输入如下额路径:
http://localhost:8090/testResponseStatusExceptionResolver?i=13
当然,也可以在方法上进行修饰:
@ResponseStatus(reason = "测试",value = HttpStatus.NOT_FOUND)
@RequestMapping("/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if (i==13){
throw new UserNameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver....");
return "success";
}
这时所有的请求都会报错。
- 仔细看这张结果图中的访问路径,我传入的参数是i=1,正常来说是不应该抛异常的,可是它抛了。。它真的抛了。。
- 结论:ResponseStatus修饰目标方法,因为你修改了响应状态码为403,并加上了错误提示(reason),所有页面回显的数据按照403错误显示页面,无论它执行方法过程中有没有异常产生,用户都会得到异常的界面。而目标方法正常执行
54. 尚硅谷_佟刚_SpringMVC_异常处理_SimpleMappingExceptionResolver.avi
SimpleMappingException异常映射
当异常发生时,我们可以将它映射到我们指定的界面
如果希望对所有异常进行统一处理,可以使用SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常:
在springmvc中配置
<!-- 配置使用 SimpleMappingExceptionResolver 来映射异常 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--
配置异常的属性值为ex,那么在错误页面中可以通过 ${ex} 来获取异常的信息
如果不配置这个属性,它的默认值为exception
-->
<property name="exceptionAttribute" value="ex"></property>
<property name="exceptionMappings">
<props>
<!-- 映射ArrayIndexOutOfBoundsException异常对应error.jsp这个页面 -->
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>
写个目标方法测试一下
@RequestMapping("/testExceptionMapping")
public String testExceptionMapping(){
int arrays[] = new int[10];
System.out.println(arrays[11]);
return "hello";
}
这里将发生数组下标越界的异常,访问目标方法,得到如下结果
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>Insert title here</title>
</head>
<body>
${ex }
</body>
</html>
这里这里的属性
${ex }必须和 <property name="exceptionAttribute" value="ex"></property>一一对应
SpringMVC 学习笔记(7)异常操作的更多相关文章
- springmvc学习笔记(简介及使用)
springmvc学习笔记(简介及使用) 工作之余, 回顾了一下springmvc的相关内容, 这次也为后面复习什么的做个标记, 也希望能与大家交流学习, 通过回帖留言等方式表达自己的观点或学习心得. ...
- SpringMVC学习笔记之二(SpringMVC高级参数绑定)
一.高级参数绑定 1.1 绑定数组 需求:在商品列表页面选中多个商品,然后删除. 需求分析:功能要求商品列表页面中的每个商品前有一个checkbok,选中多个商品后点击删除按钮把商品id传递给Cont ...
- 史上最全的SpringMVC学习笔记
SpringMVC学习笔记---- 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于Spring ...
- springmvc学习笔记--REST API的异常处理
前言: 最近使用springmvc写了不少rest api, 觉得真是一个好框架. 之前描述的几篇关于rest api的文章, 其实还是不够完善. 比如当遇到参数缺失, 类型不匹配的情况时, 直接抛出 ...
- SpringMVC:学习笔记(8)——文件上传
SpringMVC--文件上传 说明: 文件上传的途径 文件上传主要有两种方式: 1.使用Apache Commons FileUpload元件. 2.利用Servlet3.0及其更高版本的内置支持. ...
- python学习笔记5_异常
python学习笔记5_异常 1.什么事异常 Python使用异常对象(exception object) 来表示异常情况.遇到错误会发生异常. 如果异常对象未被处理或被捕捉,程序就会用所谓的回溯(t ...
- springMVC 学习笔记(一):springMVC 入门
springMVC 学习笔记(一):spring 入门 什么是 springMVC springMVC 是 spring 框架的一个模块,springMVC 和 spring 无需通过中间整合层进行整 ...
- SpringMVC:学习笔记(3)——REST
SpringMVC:学习笔记(3)——REST 了解REST风格 按照传统的开发方式,我们在实现CURD操作时,会写多个映射路径,比如对一本书的操作,我们会写多个URL,可能如下 web/delete ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
随机推荐
- Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
833. 字符串中的查找与替换 对于某些字符串 S,我们将执行一些替换操作,用新的字母组替换原有的字母组(不一定大小相同). 每个替换操作具有 3 个参数:起始索引 i,源字 x 和目标字 y.规则是 ...
- Java实现 LeetCode 341 扁平化嵌套列表迭代器
341. 扁平化嵌套列表迭代器 给你一个嵌套的整型列表.请你设计一个迭代器,使其能够遍历这个整型列表中的所有整数. 列表中的每一项或者为一个整数,或者是另一个列表.其中列表的元素也可能是整数或是其他列 ...
- Java实现 LeetCode 189 旋转数组
189. 旋转数组 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] ...
- java实现矩阵变换加密法
一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如下: 1.首先按行填入密钥串 ...
- Spring之JdbcTemplate使用
一:JdbcTemplate概述及入门 “Don‘t Reinvent the Wheel” , 这是一句很经典的话,出自Spring官方,翻译过来就是说 “不要重复发明轮子” .由此我们可以猜测,J ...
- ReentrantReadWriteLock(读写锁)全部源码注释
package java.util.concurrent.locks; import java.util.concurrent.TimeUnit; import java.util.Collectio ...
- SpringCloud多数据源实现
1.枚举多数据源-定义一一对应变量 /** * * 列出所有的数据源key(常用数据库名称来命名) * 注意: * 1)这里数据源与数据库是一对一的 * 2)DatabaseType中的变量名称就是数 ...
- Node第三方模块
node第三方模块集合 1.nrm 切换npm下载的镜像地址 nrm ls 查看可用镜像 nrm use +镜像名 2.nodemon 在控制台nodenom替代node命令执行nodejs文件, ...
- ffmpeg m3u8生成 剪辑及格式转换
使用 ffmpeg 工具, 生成 m3u8 文件 ffmpeg -re -i 03.ts -c copy -f hls -hls_base_url /Users/admin/Downloads/dow ...
- 查询局域网指定段内存活IP
目录 批量ping 输出到指定文件 批量ping for /L %i IN (起始,扫描间距,结束) DO ping -w 2 -n 1 10.224.131.%i 如 for /L %i IN (5 ...