1、springMVC异常处理概述
1.1、springMVC中的异常
在程序开发中,不管是那层的业务,都会不可避免的出现异常处理。如果每层单独处理异常,那么系统的代码的耦合度就会提高。而且工作量也会加大,不好处理。
而springMVC将所有类型的异常从各层解耦出来,进行异常的统一处理和维护。
springMVC异常处理有三种:
简单异常处理器 SimpleMappingExceptionResolver。
异常处理接口 HandlerExceptionResolver 自定义自己的异常处理器。
@ExceptionHandler 注解实现异常处理。
1.2、异常处理结构图
1.3、异常处理前的准备
1.3.1、需求
完成springMVC异常处理,创建三层架构(daoserviceview)
1.3.2、创建新项目
创建一个maven项目smvc005
1.3.3、导入jar包
pom.xml
代码语言:javascript复制 <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
代码语言:javascript复制<?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
代码语言:javascript复制<?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
代码语言:javascript复制public class DemoException extends Exception {
public DemoException(){}
public DemoException(String message){
super(message);
}
}
2.2、dao层
ExceptionDao.java
代码语言:javascript复制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
代码语言:javascript复制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
代码语言:javascript复制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
代码语言:javascript复制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
代码语言:javascript复制<%@ 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
代码语言:javascript复制<%@ 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
代码语言:javascript复制<%@ 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
代码语言:javascript复制<%@ 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
代码语言:javascript复制<%@ 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
代码语言:javascript复制<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配置
代码语言:javascript复制<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
5、HandlerExceptionResolver
org.springframework.web.servlet.HandlerExceptionResolver
5.1、加入jar包
代码语言:javascript复制<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
5.2、MyExceptionHandler
MyExceptionHandler.java
代码语言:javascript复制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
代码语言:javascript复制 <bean class="com.tyschool.smvc004.utils.MyExceptionHandler"></bean>
5.4、测试
http://localhost:8080/smvc004/index.jsp
6、@ExceptionHandler
6.1、创建异常处理类
BaseController.java
代码语言:javascript复制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
代码语言:javascript复制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