异常处理机制
系统异常分为两类:预期异常和运行时异常。
系统中dao层、service层、controller层出现异常时可以通过Throws Exception向上抛出,在Spring MVC中前端控制器将由异常处理器进行异常处理,SpringMVC 提供全局异常处理器进行统一处理,一个系统只有一个异常处理器。
下面我们通过自己写一个异常处理类来模拟一下SpringMVC中的异常处理机制。
自定义异常类
对不同的异常类型定义不同的异常类,继承Exception。
/**
* 自定义异常
* 针对预期的异常,需要在程序中抛出
*/
public class CustomException extends Exception {
//异常信息
private String message;
public CustomException(String message) {
super(message);
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
全局异常处理器
Spring MVC提供了一个HandlerExceptionResolver接口。
处理思路:
- 解析出异常类型,如果该类型是系统自定义的异常,直接取出异常信息,在错误页面展示,如果该异常类型不是系统自定义的类型,构造一个自定义的异常类型。
/**
* 异常处理器
*/
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
CustomException exception = null;
if (ex instanceof CustomException) {
exception = (CustomException)ex;
} else {
//不是系统自定义类型
exception = new CustomException("未知异常");
}
//错误信息
String message = exception.getMessage();
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", message);
modelAndView.setViewName("error");
return modelAndView;
}
}
错误页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>错误</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
配置异常处理器
<?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"
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-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<!--配置Spring MVC的需要扫描注解的包路径-->
<context:component-scan base-package="com.test.contrller"/>
<!--处理器映射器,适配器采用Spring MVC提供的默认的处理器处理,不需要显性的配置-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--配置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--全局的异常处理器-->
<bean class="com.test.exception.CustomExceptionResolver"/>
</beans>
异常的使用
/*
* 处理器
* 基于注解实现的Handler
*/
@Controller
public class ControllerDemo {
//自定义类型
//基本的数据类型
@RequestMapping("{id}")
public ModelAndView user(@PathVariable("id") int id) throws CustomException {
//可预期的异常,直接进行抛出
if (id > 35) {
System.out.println("参数非法");
throw new CustomException("参数非法");
}
Random random = new Random();
//模拟一个不可预期的异常
int i = id / random.nextInt(2);//0 1
User user = new User();
user.setId(1);
user.setUserName("lisi");
user.setSex("男");
user.setAddress("西安");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("user",user);
modelAndView.setViewName("editUser");
return modelAndView;
}
}
- 在这里我们模拟url参数非法的场景,例如我们数据库中学生最多有35人,那么当id大于35时,即该url参数非法。