springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

一、异常处理思路

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

spring 捕获 数据库异常 springmvc捕获全局异常_异常处理

二、自定义异常类

为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。

package com.jiayifan.ssm.exception;
/**
 * 系统自定义异常类
 * @author 贾一帆
 *
 */
public class CustomException extends Exception {
    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;
    }

}
三、自定义异常处理器
package com.jiayifan.ssm.exception;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

/**
 * 全局异常处理器
 * @author 贾一帆
 *
 */
public class CustomExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            Exception exception) {
        //handler就是处理器适配器要执行的Handler对象(只有method)
        //解析出异常类型
        //如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示
        CustomException customException = null;
        if(exception instanceof CustomException){
            customException = (CustomException)exception;
        }else{
            customException = new CustomException("未知错误");
        }
        //错误信息
        String message = customException.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"%>
<!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>
${message }
</body>
</html>
五、异常处理器配置

springmvc.xml中添加:

<!-- 全局异常处理器 
    只有实现了 HandlerExceptionResolver接口就是全局异常处理器
    -->
    <bean class="com.jiayifan.ssm.exception.CustomExceptionResolver"></bean>
六、异常测试

controller、service、dao中任意一处需要手动抛出异常。
如果是程序中手动抛出的异常,在错误页面中显示自定义的异常信息,如果不是手动抛出异常说明是一个运行时异常,在错误页面只显示“未知错误”。
在商品修改的controller方法中抛出异常:

@RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
    //@RequestParam中的value属性指定request传入的参数名称
    //通过required属性指定这个参数是否必须要传入
    //通过defaultValue属性可以设置默认值,如果id参数没有传入,就会将默认值和形参绑定
    public String editItems(Model model,@RequestParam(value="id",required=true,defaultValue="1") Integer items_id) throws Exception {
        //调用sercice查询商品信息
        ItemsCustom itemsCustom = itemsService.findItemsById(items_id);
        //判断商品是否为空
        if(itemsCustom == null) {
            throw new CustomException("controller中修改的商品信息不存在");
        }
        //通过参数中的model将数据传到页面
        model.addAttribute("itemsCustom",itemsCustom);
        return "items/editItems";
    }

spring 捕获 数据库异常 springmvc捕获全局异常_异常处理_02


service接口中抛出异常:

@Override
    public ItemsCustom findItemsById(Integer id) throws Exception {
        Items items = itemsMapper.selectByPrimaryKey(id);
        if(items == null) {
            throw new CustomException("service中修改的商品信息不存在");
        }
        //中间对商品信息进行业务处理
        //业务处理代码
        //返回扩展类
        ItemsCustom itemsCustom = null;
        //将items的内容拷贝到itemsCustom中
        if(items != null) {
            itemsCustom = new ItemsCustom();
            BeanUtils.copyProperties(items, itemsCustom);
        }

        return itemsCustom;
    }

spring 捕获 数据库异常 springmvc捕获全局异常_springmvc_03