异常处理
异常处理思路:
系统中的异常包括两类:预期异常和运行异常,前者通过捕获异常而获取异常,后者通过规范代码开发,通过测试手段减少运行时异常的发生。
图源:《传智播客·黑马程序员》
简单阐述上图思路:
系统的dao层,service层,controller层都通过throws Exception向上抛出异常,再由springmvc的前端控制器交给全局异常处理器进行异常处理。
Springmvc提供全局异常处理器统一进行异常处理(一个系统只有一个异常处理器)。
自定义异常类
对不同异常类型创建异常类,继承Exception
CustomException.java
package cn.ssm.xhchen.exception;
/**
*
* ClassName: CustomException
*
* @Description: 商品自定义异常类
* @author XHChen
* @date 2018年11月6日 下午7:09:11
*/
public class CustomException extends Exception {
/**
* @Fields serialVersionUID : TODO
*/
private static final long serialVersionUID = 1L;
// 异常信息
private String message;
public CustomException(String message) {
super(message);
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
创建全局异常处理器
处理思路:
解析出异常类型
如果异常类型为自定义异常,直接取出异常信息,在指定页面显示
如果异常类型不是自定义异常,构造一个自定义异常类型
创建全局异常处理器,实现Springmvc提供的HandlerExceptionResolver接口
CustomExceptionResolve.java
package cn.ssm.xhchen.exception;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
/**
*
* ClassName: CustomExceptionResolve
*
* @Description: 全局异常处理器
* @author XHChen
* @date 2018年11月6日 下午7:27:54
*/
public class CustomExceptionResolve implements HandlerExceptionResolver {
/**
* 构造方法一
*/
/*@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object obj, Exception ex) {
// 解析出异常类型
String message = null;
if (ex instanceof CustomException) {
// 如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示
message = ((CustomException)ex).getMessage();
} else {
// 如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
message = "未知错误";
}
// 创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
// 返回数据到页面
modelAndView.addObject("message", message);
// 指定视图
modelAndView.setViewName("error");
// 返回视图
return modelAndView;
}*/
}
一般使用下面方法代替上面的方法,交给自定义异常类处理
/**
* 构造方法二
*/
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object obj, Exception ex) {
// 解析出异常类型
CustomException customException = null;
if (ex instanceof CustomException) {
// 如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示
customException = (CustomException) ex;
} else {
// 如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
customException = new CustomException("未知错误");
}
// 错误信息
String message = customException.getMessage();
// 创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
// 返回数据到页面
modelAndView.addObject("message", message);
// 指定视图
modelAndView.setViewName("error");
// 返回视图
return modelAndView;
}
错误页面
error.jsp
引入jstl
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
页面编写
<body>
${message }
</body>
在springmvc.xml中配置全局异常处理器
<!-- 全局异常处理器
必须实现HandlerExceptionResolver接口
-->
<bean class="cn.ssm.xhchen.exception.CustomExceptionResolve"></bean>
异常测试
在商品修改的controller方法中抛出异常
/**
*
* @Description: 商品信息修改页面
* @param @param request 通过request对象获取请求信息
* @param @param id 商品信息id
* @param @return 返回修改页面
* @param @throws Exception
* @return ModelAndView
* @throws
* @author XHChen
* @date 2018年10月26日 上午10:16:06
*/
// 1.Integer id,要求request返回参数名称与controller形参名称一致
// 2.@RequestParam对简单类型的参数进行绑定
// a.@RequestParam,指定request返回参数名称与controller形参名称绑定
// b.required,指定参数必须传入
// c.defaultValue,id默认参数
@RequestMapping("/editItems.action")
public ModelAndView editItems(HttpServletRequest request,
@RequestParam(value = "id", required = true, defaultValue = "id") Integer id)
throws Exception {
// 调用itemsService接口,查询商品信息
ItemsCustomer itemsCustomer = itemsService.findItemsById(id);
// 异常处理
if (itemsCustomer == null) {
throw new CustomException("修改的商品不存在!!!");
}
// 创建ModelAndView
ModelAndView modelAndView = new ModelAndView();
// 返回数据到页面
modelAndView.addObject("itemsCustomer", itemsCustomer);
// 指定视图
// 路径前缀和后缀已由springmvc.xml配置
modelAndView.setViewName("items/editItems");
// 返回指定视图
return modelAndView;
}
在service接口中抛出异常
如果与业务功能相关的异常,建议在service中抛出异常。
与业务功能没有关系的异常,建议在controller中抛出。
@Override
/**
* 根据id查询商品信息
*/
public ItemsCustomer findItemsById(Integer id) throws Exception {
// 根据id查询商品信息
Items items = itemsMapper.findItemsById(id);
// 抛出异常
if (items == null) {
throw new CustomException("修改的商品不存在!!!");
}
// 创建ItemsCustomer对象
ItemsCustomer itemsCustomer = new ItemsCustomer();
// 把商品信息items复制到itemsCustomer
BeanUtils.copyProperties(items, itemsCustomer);
// 返回拓展类ItemsCustomer
return itemsCustomer;
}