共计 11776 个字符,预计需要花费 30 分钟才能阅读完成。
1、springMVC 异常处理概述
1.1、springMVC 中的异常
在程序开发中,不管是那层的业务,都会不可避免的出现异常处理。如果每层单独处理异常,那么系统的代码的耦合度就会提高。而且工作量也会加大,不好处理。
而 springMVC 将所有类型的异常从各层解耦出来,进行异常的统一处理和维护。
springMVC 异常处理有三种:
简单异常处理器 SimpleMappingExceptionResolver。
异常处理接口 HandlerExceptionResolver 自定义自己的异常处理器。
@ExceptionHandler 注解实现异常处理。
1.2、异常处理结构图
1.3、异常处理前的准备
1.3.1、需求
完成 springMVC 异常处理,创建三层架构(dao\service\view)
1.3.2、创建新项目
创建一个 maven 项目 smvc005
1.3.3、导入 jar 包
pom.xml
<properties>
<spring.version>5.2.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
1.3.4、配置 web.xml
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>Archetype Created Web Application</display-name>
<!-- 配置 SpringMVC 核心, 前置控制器 DispatcherServlet -->
<servlet>
<servlet-name>SpringMVCDispathcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化参数,用来读取 springmvc.xml 文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc.xml</param-value>
</init-param>
<!-- 配置 servlet 的对象的创建时间点:应用加载时创建。取值只能是非 0 正整数,表示启动顺序 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 前置控制器,映射所有地址 -->
<servlet-mapping>
<servlet-name>SpringMVCDispathcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.3.5、配置 springmvc.xml
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置扫描器,扫描注解 -->
<context:component-scan base-package="com.tyschool.smvc004"></context:component-scan>
<!-- 配置视图解析器,配置前缀和后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
1.3.6、启动服务
http://localhost:8080/smvc004/index.jsp
2、配置各层异常
2.1、自定义异常类
DemoException.java
public class DemoException extends Exception {public DemoException(){}
public DemoException(String message){super(message);
}
}
2.2、dao 层
ExceptionDao.java
package com.tyschool.smvc004.dao;
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.stereotype.Repository;
import java.sql.SQLException;
@Repository("exceptionDao")
public class ExceptionDao {public void dbDao() throws Exception{throw new SQLException("数据库异常 -dao");
}
public void myDao() throws Exception{throw new DemoException("自定义异常 -dao");
}
public void noDao() throws Exception{throw new SQLException("未知异常 -dao");
}
}
2.3、service 层
IExceptionService.java
public interface IExceptionService {public void myService()throws Exception;
public void dbService()throws Exception;
public void noService()throws Exception;
public void myDao()throws Exception;
public void dbDao()throws Exception;
public void noDao()throws Exception;
}
ExceptionServiceImpl.java
import com.tyschool.smvc004.dao.ExceptionDao;
import com.tyschool.smvc004.service.IExceptionService;
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.SQLException;
@Service("exceptionServiceImpl")
public class ExceptionServiceImpl implements IExceptionService {@Autowired
private ExceptionDao exceptionDao;
@Override
public void myService() throws Exception {throw new DemoException("自定义异常 -Service");
}
@Override
public void dbService() throws Exception {throw new SQLException("数据库异常 -Service");
}
@Override
public void noService() throws Exception {throw new SQLException("未知异常 -Service");
}
@Override
public void myDao() throws Exception {exceptionDao.myDao();
}
@Override
public void dbDao() throws Exception {exceptionDao.dbDao();
}
@Override
public void noDao() throws Exception {exceptionDao.noDao();
}
}
2.4、控制器 controller
ExceptionController.java
import com.tyschool.smvc004.service.IExceptionService;
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.sql.SQLException;
@Controller("exceptionController")
public class ExceptionController {@Autowired
@Qualifier("exceptionServiceImpl")
private IExceptionService exceptionService;
@RequestMapping("/db")
public void db() throws Exception{throw new SQLException("数据库异常 -Controller");
}
@RequestMapping("/my")
public void my() throws Exception{throw new DemoException("自定义异常 -Controller");
}
@RequestMapping("/no")
public void no() throws Exception{throw new SQLException("未知异常 -Controller");
}
@RequestMapping("/dbS")
public void dbService() throws Exception{exceptionService.dbService();
}
@RequestMapping("/myS")
public void myService() throws Exception{exceptionService.myService();
}
@RequestMapping("/noS")
public void noServcie() throws Exception{exceptionService.noService();
}
@RequestMapping("/dbD")
public void dbDao() throws Exception{exceptionService.dbDao();
}
@RequestMapping("/myD")
public void myDao() throws Exception{exceptionService.myDao();
}
@RequestMapping("/noD")
public void noDao() throws Exception{exceptionService.noDao();
}
}
3、创建 view 层
3.1、首页
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3><a href="${pageContext.request.contextPath}/dbD"> 处理 dao 中数据库异常 </a></h3>
<h3><a href="${pageContext.request.contextPath}/myD"> 处理 dao 中自定义异常 </a></h3>
<h3><a href="${pageContext.request.contextPath}/noD"> 处理 dao 未知异常 </a></h3>
<hr>
<h3><a href="${pageContext.request.contextPath}/dbS"> 处理 service 中数据库异常 </a></h3>
<h3><a href="${pageContext.request.contextPath}/myS"> 处理 service 中自定义异常 </a></h3>
<h3><a href="${pageContext.request.contextPath}/noS"> 处理 service 未知异常 </a></h3>
<hr>
<h3><a href="${pageContext.request.contextPath}/db"> 处理 controller 中数据库异常 </a></h3>
<h3><a href="${pageContext.request.contextPath}/my"> 处理 controller 中自定义异常 </a></h3>
<h3><a href="${pageContext.request.contextPath}/no"> 处理 controller 未知异常 </a></h3>
<hr>
<!-- 在 web.xml 中配置404 -->
<h3>
<a href="${pageContext.request.contextPath}/404">404 错误 </a>
</h3>
</body>
</html>
3.2、404
404.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>404</title>
</head>
<body>
没能找到资源!</body>
</html>
3.3、error
/pages/error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>error</title>
</head>
<body>
<H1> 未知错误:</H1><%=exception %>
<H2> 错误内容:</H2>
<%
exception.printStackTrace(response.getWriter());
%>
</body>
</html>
3.4、my-error
/pages/my-error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>my-error</title>
</head>
<body>
<H1> 自定义异常错误:</H1><%=exception %>
<H2> 错误内容:</H2>
<%
exception.printStackTrace(response.getWriter());
%>
</body>
</html>
3.5、sql-error
/pages/sql-error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>sql-error</title>
</head>
<body>
<H1> 数据库异常错误:</H1><%=exception %>
<H2> 错误内容:</H2>
<%
exception.printStackTrace(response.getWriter());
%>
</body>
</html>
3.6、测试
http://localhost:8080/smvc004/index.jsp
4、SimpleMappingExceptionResolver
org.springframework.web.servlet.handler.SimpleMappingExceptionResolver
springmvc.xml
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定义默认的异常处理页面,当该异常类型注册时使用 -->
<property name="defaultErrorView" value="error"></property>
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为 exception -->
<property name="exceptionAttribute" value="exception"></property>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为 key,异常页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="com.tyschool.smvc004.utils.DemoException">my-error</prop>
<prop key="java.sql.SQLException">sql-error</prop>
<!-- 在这里还可以继续扩展对不同异常类型的处理 -->
</props>
</property>
</bean>
404 配置
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
5、HandlerExceptionResolver
org.springframework.web.servlet.HandlerExceptionResolver
5.1、加入 jar 包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
5.2、MyExceptionHandler
MyExceptionHandler.java
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
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("exception",e);
if(e instanceof DemoException){return new ModelAndView("my-error",model);
}else if(e instanceof SQLException){return new ModelAndView("sql-error",model);
}else{return new ModelAndView("error",model);
}
}
}
5.3、配置 bean
Springmvc.xml
<bean class="com.tyschool.smvc004.utils.MyExceptionHandler"></bean>
5.4、测试
http://localhost:8080/smvc004/index.jsp
6、@ExceptionHandler
6.1、创建异常处理类
BaseController.java
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
public class BaseController {/** 基于 @ExceptionHandler 异常处理 */
@ExceptionHandler
public String exception(HttpServletRequest request, Exception ex) {request.setAttribute("exception", ex);
// 根据不同错误转向不同页面,即异常与 view 的对应关系
if (ex instanceof SQLException) {return "sql-error";
} else if (ex instanceof DemoException) {return "my-error";
} else {return "error";
}
}
}
6.2、创建新控制器
TestExceptionController.java
import com.tyschool.smvc004.service.IExceptionService;
import com.tyschool.smvc004.utils.DemoException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.sql.SQLException;
@Controller("testExceptionController")
public class TestExceptionController extends BaseController {@Autowired
@Qualifier("exceptionServiceImpl")
private IExceptionService exceptionService;
@RequestMapping("/db")
public void db() throws Exception{throw new SQLException("数据库异常 -Controller");
}
@RequestMapping("/my")
public void my() throws Exception{throw new DemoException("自定义异常 -Controller");
}
@RequestMapping("/no")
public void no() throws Exception{throw new SQLException("未知异常 -Controller");
}
@RequestMapping("/dbS")
public void dbService() throws Exception{exceptionService.dbService();
}
@RequestMapping("/myS")
public void myService() throws Exception{exceptionService.myService();
}
@RequestMapping("/noS")
public void noServcie() throws Exception{exceptionService.noService();
}
@RequestMapping("/dbD")
public void dbDao() throws Exception{exceptionService.dbDao();
}
@RequestMapping("/myD")
public void myDao() throws Exception{exceptionService.myDao();
}
@RequestMapping("/noD")
public void noDao() throws Exception{exceptionService.noDao();
}
}
6.3、测试
http://localhost:8080/smvc004/index.jsp