统一异常处理
SpringMVC统一异常处理常用有三种方式:
- 简单异常处理 SimpleMappingExceptionResolver类
- HandlerExceptionResolver接口
- @ExceptionHandler注解
一、通常抛出异常信息方法
1. 在SpringMVC项目中
导入相关依赖。
目录结构:
2. 新建MyException自定义异常类
package main.java.springmvc.exception.utils;
/**
* @author xry
* 自定义异常类
*/
public class MyException extends Exception {
private static final long serialVersionUID = 1L;
public MyException() {
super();
}
public MyException(String message) {
super(message);
}
}
3. 在dao、server和controller中添加方法
做一个简单的springmvc测试项目
dao层
/**
* @author xry
*/
@Repository
public class TestExceptionDao {
public void daodb() throws Exception {
throw new SQLException("Dao中数据库异常");
}
public void daomy() throws Exception {
throw new MyException("Dao中自定义异常");
}
public void daono() throws Exception {
throw new Exception("Dao中未知异常");
}
}
server接口层
public interface TestExceptionService {
//调用dao层方法
public void daomy() throws Exception;
public void daodb() throws Exception;
public void daono() throws Exception;
}
serveriml实现层
/**
* @author xry
*/
@Service
public class TestExceptionServiceImpl implements TestExceptionService {
@Autowired
private TestExceptionDao testExceptionDao;
@Override
public void daomy() throws Exception {
testExceptionDao.daomy();
}
@Override
public void daodb() throws Exception {
testExceptionDao.daodb();
}
@Override
public void daono() throws Exception {
testExceptionDao.daono();
}
}
controller 控制器层
/**
* @author xry
*/
@Controller
public class TestExceptionController {
@Autowired
private TestExceptionService testExceptionService;
//进入测试界面
@RequestMapping("/toTestException")
public String test() {
return "testexception";
}
//以daomy方法自定义异常为例
@RequestMapping("/my")
public void my() throws Exception {
testExceptionService.daomy();
}
}
4. 新建视图层
测试界面testexception.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/my">自定义异常</a><hr>
<a href="${pageContext.request.contextPath}/404">404错误</a>
</body>
</html>
自定义异常界面 my-error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>自定义异常</h1><%=exception%>
<h2>错误信息</h2>
<%
exception.printStackTrace(response.getWriter());
%>
</body>
</html>
通常web.xml中可以配置全局异常404处理来处理那些Unchecked Exception.
404界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>404error</title>
</head>
<body>
<h1>404error</h1>
</body>
</html>
5. 在springmvc核心配置文件中进行配置
<!--开启注解扫描-->
<context:component-scan base-package="main.java.springmvc.exception"/>
在web.xml中配置全局异常处理404
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
6. 测试
启动项目进入测试界面
测试自定义异常
抛出了异常信息。
测试404
假如在路径上多加个”1“
访问则会
由以上结果可以看出,普通的方法只是通过throw 和 throws抛出异常,而没有进行处理。因此需要进一步进行处理。
二、SimpleMappingExceptionResolver类
org.springframework.web.servlet.handler.SimpleMappingExceptionResolver类统一处理异常需要在配置文件中提前配置异常类和View的对应关系。
springmvc核心配置文件中进行如下配置。异常类为建好的MyException类,对应的页面为my-error.jsp。
<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="main.java.springmvc.exception.utils.MyException">my-error</prop>
<!--可以继续扩展不同的异常处理类型-->
</props>
</property>
</bean>
测试结果
启动项目
测试自定义异常
可以看到,进入到了我们自定义的异常处理的界面。
三、HandlerExceptionResolver接口
org.springframework.web.servlet.HandlerExceptionResolver接口用于解析请求处理过程中所产生的的异常。
需要创建一个类来实现这个接口
1.新建实现类MyExceptionHandler
/**
* @author xry
*/
public class MyExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("ex", e);
//根据不同错误转向不同页面,即异常与View的对应关系
if (e instanceof MyException) {
return new ModelAndView("my-error", model);
}else {
return new ModelAndView("error",model);
}
}
}
2.将实现类托管给springmvc框架
<!-- <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="main.java.springmvc.exception.utils.MyException">my-error</prop>
<!–可以继续扩展不同的异常处理类型–>
</props>
</property>
</bean>-->
<!--托管MyExceptionHandler 或者在MyExceptionHandler 类上注解为Bean-->
<bean class="main.java.springmvc.exception.utils.MyExceptionHandler"/>
测试结果一致
四、@ExceptionHandler注解
需要创建一个baseController类,并在类中使用@ExceptionHandler注解注解声明异常处理方法。
/**
* @author xry
*/
public abstract class BaseController {
@ExceptionHandler
public String exception(HttpServletRequest request, Exception ex) {
request.setAttribute("ex", ex);
//根据不同错误转向不同页面,即异常与View的对应关系
if (ex instanceof MyException) {
return "my-error";
}else {
return "error";
}
}
}
并在需要异常的控制器类上继承BaseController类。
@Controller
public class TestExceptionController extends BaseController {
@Autowired
private TestExceptionService testExceptionService;
@RequestMapping("/toTestException")
public String test() {
return "testexception";
}
@RequestMapping("/my")
public void my() throws Exception {
testExceptionService.daomy();
}
}
测试结果一致。
至此,SpringMVC统一异常处理常用有三种方式的基本使用已经完成,三种方式各有优势。