SpringMVC 的异常处理
# 110.SpringMVC 的异常处理
Controller 调用 service,service 调用 dao,异常都是向上抛出的,最终由 DispatcherServlet 找异常处理器进行异常的处理
# 异常处理过程
我们经常会遇到异常,但是对于用户而言,最好有一些友好的异常页面,例如“网站正在维护中”等,而不是直接将异常处理信息给到客户。
我们的异常都是向上抛出的,如果前端控制器不进行处理,那么异常信息就会直接给到浏览器:
SpringMVC 有一个组件是异常处理器,可以对异常进行处理,然后异常处理器处理完异常,可以返回一个准备好的错误页面(例如上面显示“网站真正维护中”),用户看到的就是一个友好的错误页面
# 环境准备
我们删除之前的 Java 代码,重新搭建环境。
# 新建超链接
修改 index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>异常标签</h3>
<a href="user/textException">异常处理</a>
</body>
</html>
2
3
4
5
6
7
8
9
10
新增成功页面:webapp/WEB-INF/pages/success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>执行成功</h3>
</body>
</html>
2
3
4
5
6
7
8
9
10
# 新增控制器方法
package com.peterjxl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/textException")
public String textException() throws Exception {
System.out.println("UserController.textException()");
return "success";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 模拟异常
我们模拟一个异常:
@RequestMapping("/textException")
public String textException() throws Exception {
System.out.println("UserController.textException()");
// 模拟异常
int i = 1/0;
return "success";
}
2
3
4
5
6
7
8
之前我们说过,如果我们不定义异常处理器,异常信息是会直接给到客户的,不友好:
# 定义异常处理器的步骤:
- 我们首先编写一个自定义异常类(做提示信息)
- 编写异常处理器
- 配置异常处理器(跳转到提示页面)
# 新建异常类
package com.peterjxl.exception;
public class SysException extends Exception{
private String message;
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SysException(String message) {
this.message = message;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 抛出自定义异常
由于我们自定义了异常类,我们可以抛出自定义的异常:
@RequestMapping("/textException")
public String textException() throws Exception {
System.out.println("UserController.textException()");
// 模拟异常
try {
int i = 1/0;
} catch (Exception e) {
e.printStackTrace();
throw new SysException("出现错误");
}
return "success";
}
2
3
4
5
6
7
8
9
10
11
12
13
# 编写异常处理器
我们新建一个类,并实现其接口和方法:
package com.peterjxl.exception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 异常处理器
*/
public class SysExceptionResolver implements HandlerExceptionResolver {
/**
* 处理异常业务逻辑
*/
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception ex) {
return null;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
resolveException 方法中,handler 是当前处理器对象,用的少。
ex 是异常对象,例如本例中就是 SysException。
返回值是 ModelAndView,之前我们说过可以设置该对象,以实现跳转到某个页面。
接下来我们配置下处理逻辑:
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception ex) {
// 获取到异常对象
SysException e = null;
if (ex instanceof SysException) {
e = (SysException) ex;
} else {
e = new SysException("系统正在维护...");
}
// 创建ModelAndView对象
ModelAndView mv = new ModelAndView();
mv.addObject("errorMsg", e.getMessage());
mv.setViewName("error");
return mv;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 配置异常处理器
我们在 springmvc.xml 中配置:
<!-- 配置异常处理器 -->
<bean id="sysExceptionResolver" class="com.peterjxl.exception.SysExceptionResolver"/>
2
# 新建错误页面
我们新建一个 webapp/WEB-INF/pages/error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${errorMsg}
</body>
</html>
2
3
4
5
6
7
8
9
# 测试
我们重启,访问并测试,可以看到跳转到了友好的错误页面,并且 IDE 控制台里有打印异常信息
# 源码
本项目已将源码上传到 GitHub (opens new window) 和 Gitee (opens new window) 上。并且创建了分支 demo10,读者可以通过切换分支来查看本文的示例代码。
- 01
- 中国网络防火长城简史 转载10-12
- 03
- 公告:博客近期 RSS 相关问题10-02