本文目录
统一异常处理概述
在项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。 SpringMVC支持将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护
Spring MVC
处理异常有3种方式:
(1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;
(2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
(3)使用@ExceptionHandler注解实现异常处理;
创建工程和添加相关文件
参考 【SpringMVC】SpringMVC入门实例创建一个SpringMVC工程
创建完工程以后添加一些文件如下:
jsp页面
404.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>404找不到页面</h2>
</body>
</html>
myexception.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>myexception异常页面</h2>
</body>
</html>
sqlexception.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>数据库出错异常页面</h2>
</body>
</html>
自定义异常类
public class MyException extends Exception {
private String message;
public MyException(String message) {
super(message);
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
ExceptionControl
ExceptionControl
添加了两个请求,myexception请求抛出一个自定义异常,sqlexception中抛出一个数据库异常
@Controller
@RequestMapping("/exception")
public class ExceptionControl {
@RequestMapping(value = "/myexception")
public void myexception() throws Exception {
throw new MyException("自定义异常");
}
@RequestMapping(value = "/sqlexception")
public void sqlexception() throws Exception {
throw new SQLException("数据库异常");
}
}
404统一处理
在web.xml
中添加404页面不存在的统一处理
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/404.jsp</location>
</error-page>
当请求一个不存在的请求时,统一跳转到404.jsp
页面
异常页面可以根据实际需求自行美化
异常处理方法
方法1:使用SimpleMappingExceptionResolver实现异常处理
在Spring的配置文件中增加以下内容
<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="com.lucas.controller.MyException">myexception</prop>
<prop key="java.sql.SQLException">sqlexception</prop>
<!-- 这里还可以继续扩展对不同异常类型的处理 -->
</props>
</property>
</bean>
访问自定义异常请求
异常页面可以根据实际需求自行美化
访问数据库异常请求
方法2:使用HandlerExceptionResolver 接口实现异常处理
增加HandlerExceptionResolver 接口的实现类MyExceptionHandler,代码如下
public class MyExceptionHandler implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("ex", ex);
// 根据不同错误转向不同页面
if(ex instanceof MyException) {
return new ModelAndView("myexception", model);
}else if(ex instanceof SQLException) {
return new ModelAndView("sqlexception", model);
} else {
return new ModelAndView("404", model);
}
}
}
Spring配置文件中增加bean
<bean id="exceptionHandler" class="com.lucas.controller.MyExceptionHandler"/>
运行结果同方法1
方法3:使用@ExceptionHandler注解实现异常处理;
增加BaseController类,并在类中使用@ExceptionHandler注解声明异常处理,代码如下:
public abstract class BaseController {
@ExceptionHandler
public String exp(HttpServletRequest request, Exception ex) {
request.setAttribute("ex", ex);
// 根据不同错误转向不同页面
if(ex instanceof MyException) {
return "myexception";
}else if(ex instanceof SQLException) {
return "sqlexception";
} else {
return "404";
}
}
}
修改代码,使所有需要异常处理的Controller都继承该类
运行结果同方法1