系统中异常包括两类:编译期异常和运行时异常
系统中的三层架构(dao、service、controller)都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>4.3.18.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.5version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.5version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.5version>
dependency>
dependencies>
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter>
<filter-name>HttpPutFormContentFilterfilter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<welcome-file-list>
<welcome-file>/views/index.jspwelcome-file>
welcome-file-list>
web-app>
springmvc.xml
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.newcapec"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-handler/>
beans>
BusinessExeption.java
public class BusinessExeption extends Exception {
public BusinessExeption(){
super("商务异常");
}
}
CustomException.java
public class CustomException extends Exception {
public CustomException(){
super("客户异常");
}
}
接口
public interface DemoDao {
void insert(String name) throws Exception;
}
实现类
@Repository("demoDao")
public class DemoDaoImpl implements DemoDao {
@Override
public void insert(String name) throws Exception {
System.out.println("dao执行了..." + name);
//模拟异常
if("null".equals(name)){
System.out.println("空指针异常出现...");
String s = null;
s.trim();
}else if("business".equals(name)){
System.out.println("商务异常出现...");
throw new BusinessExeption();
}else if("custom".equals(name)){
System.out.println("客户异常出现...");
throw new CustomException();
}else{
System.out.println("未出现异常,程序正常...");
}
}
}
接口
public interface DemoService {
void add(String name) throws Exception;
}
实现类
@Service("demoService")
public class DemoServiceImpl implements DemoService {
@Autowired
private DemoDao demoDao;
@Override
public void add(String name) throws Exception {
System.out.println("service执行了...");
demoDao.insert(name);
}
}
@Controller
@RequestMapping("/demo")
public class DemoController {
@Autowired
private DemoService demoService;
@RequestMapping("/add")
public String add(String name) throws Exception {
System.out.println("controller执行了...");
//在controller中调用业务逻辑层
demoService.add(name);
return "success";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center">
<h1>异常处理h1>
<form action="demo/add" method="post">
<p>数据:<input type="text" name="name">p>
<p><button>提交button>p>
form>
div>
body>
html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center;">
<h1>跳转成功!!!h1>
div>
body>
html>
使用springmvc提供的简单异常处理器SimpleMappingExceptionResolver,在springmvc.xml配置如下:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"/>
<property name="exceptionAttribute" value="ex"/>
<property name="exceptionMappings">
<props>
<prop key="com.newcapec.myexception.BusinessExeption">error_busprop>
<prop key="com.newcapec.myexception.CustomException">error_custprop>
props>
property>
bean>
异常跳转页面如下:
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center">
<h1 style="color: red;">系统故障,请联系管理员!h1>
<p>异常信息:${ex}p>
<p>自定义信息:${msg}p>
div>
body>
html>
error_bus.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center;">
<h1>商务异常出现后的跳转页面h1>
<p>异常信息:${ex}p>
<p>自定义信息:${msg}p>
div>
body>
html>
error_cust.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Titletitle>
head>
<body>
<div style="text-align: center;">
<h1>客户异常出现后的跳转页面h1>
<p>异常信息:${ex}p>
<p>自定义信息:${msg}p>
div>
body>
html>
实现SpringMVC的异常处理接口HandlerExceptionResolver定义自己的异常处理器,代码如下:
/**
* 自定义全局异常处理器
* 1.实现HandlerExceptionResolver接口并实现其中抽象方法
* 2.将异常处理器对象放入ioc容器中
*/
@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
/**
* 处理异常的方法
* @param request 请求对象
* @param response 响应对象
* @param handler 处理器对象
* @param ex 抛出的异常对象
* @return ModelAndView对象
*/
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
ModelAndView mav = new ModelAndView();
// 根据不同异常向不同的页面跳转
if(ex instanceof BusinessExeption){
request.setAttribute("msg", "message for business exception");
mav.setViewName("error_bus");
}else if(ex instanceof CustomException){
request.setAttribute("msg", "message for custom exception");
mav.setViewName("error_cust");
}else {
request.setAttribute("msg", "message for other exception");
mav.setViewName("error");
}
return mav;
}
}
在Controller中使用@ExceptionHandler注解实现异常处理
@Controller
@RequestMapping("/other")
public class OtherController {
@RequestMapping("/add")
public String add() throws Exception {
System.out.println("其他处理器中的异常...");
//模拟异常
Class.forName("abc");
return "success";
}
/**
* 在Controller中定义一个处理异常的方法
* 方法的如果是String类型,表示异常跳转的路径视图名
*
* @ExceptionHandler
* 位置:方法
* 作用:使当前方法可处理异常
* 属性:value = 当前方法将要处理异常的类型(异常的Class类型)
*
* 注意:如果@ExceptionHandler使用在某个Controller,那么它只能处理该Controller抛出的异常
*/
@ExceptionHandler(Exception.class)
public String handleException(Model model){
model.addAttribute("msg", "注解式异常处理");
return "error";
}
}
注意:进行异常处理的方法必须与抛出异常的方法在同一个Controller里面,不能全局控制异常
使用@ControllerAdvice + @ExceptionHandler注解实现全局异常处理
/**
* @ControllerAdvice
* 位置:类
* 作用:注解式全局异常处理器
*/
@ControllerAdvice
public class MyControllerAdvice {
@ExceptionHandler(BusinesException.class)
public String handleBusinesException(Model model){
model.addAttribute("msg", "注解式异常处理的商务异常");
return "error_bus";
}
@ExceptionHandler(CustomException.class)
public String handleCustomException(Model model){
model.addAttribute("msg", "注解式异常处理的客户异常");
return "error_cust";
}
@ExceptionHandler(Exception.class)
public String handleException(Model model){
model.addAttribute("msg", "注解式异常处理的其他异常");
return "error";
}
}
在异常处理的方法中,使用@ResponseBody注解响应客户端即可
Controller中的方法:
@ResponseBody
@RequestMapping("/get")
public String get(String id) throws Exception {
System.out.println("处理异步请求的方法执行了...");
//模拟异常
int i = Integer.parseInt(id);
System.out.println("编号:" + i);
return "success";
}
处理异常的方法:
/**
* 处理异步请求中出现的异常
*/
@ResponseBody
@ExceptionHandler(value = NumberFormatException.class)
public String handleAsyncException(){
return "error";
}
页面中的异步请求:
<script type="text/javascript" src="js/jquery-3.3.1.min.js">script>
<script type="text/javascript">
function get() {
$.ajax({
url : "demo/get",
type : "get",
data : {
id : "10"},
success : function (data) {
alert(data);
}
});
}
script>
<p><a href="javascript:get()">异步请求a>p>