Spring MVC 的异常处理

Spring MVC 异常处理有两种方法:

一、使用@ExceptionHandler标识处理异常的方法(不推荐

在需要做异常处理的类中写一个方法,方法用@ExceptionHandler标识,当这个类中有方法发生异常时,@ExceptionHandler标识的方法就会捕获到该异常,进而对其进行处理,如下:

/**
 * @ExceptionHandler 捕获当前类的异常
 * ({Exception.class}) 指定捕获特定的异常
 * Exception e :捕获到的异常对象
 * ModelAndView:给异常页面传递数据,必须使用它,其他的不行(至少model和map不行)。
 * @ExceptionHandler 捕获异常是有优先级的,距离指定异常越近,就执行那一个方法
 */
@ExceptionHandler({Exception.class})
public ModelAndView test(Exception e){
    System.out.println("出现异常了,异常是:" + e);
    ModelAndView mav = new ModelAndView("error");
    mav.addObject("e",e);
    return mav;
}
@ResponseBody
@ExceptionHandler({NumberFormatException.class})
public String test2(Exception e){
    System.out.println("【出现异常了,异常是】:" + e);
    return "出现异常了";
}

//文章列表页面
@RequestMapping("/list/page")
public String listPage(){
    int a = Integer.parseInt("a");
    return "admin/content/admin-blog-content-list";
}

当请求listPage()方法时,如果出现异常,异常就会被上面两个@ExceptionHandler标识的方法捕获到,这里有两个方法,那么该执行哪一个呢?这个就涉及到捕获异常的优先级了。
发生异常时,如果当前类有多个@ExceptionHandler标识的方法,那么那个方法越接近异常,那么就执行那个方法。

二、使用@ControllerAdvice定义全局异常(推荐)

使用第一种方法时,如果有多个类都要使用捕获异常,那么没有类都要使用@ExceptionHandler标识方法,太麻烦了。

现在直接通过@ControllerAdvice定义一个全局的捕获异常的类,所有的类出现异常都会被@ControllerAdvice定义的类所捕获。

/**
 * 全局异常
 */
@ControllerAdvice //定义全局异常,异常集中处理,更好的使业务逻辑与异常处理剥离开
public class CommExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = {Exception.class})//统一处理某一类异常,从而能够减少代码重复率和复杂度
    public Msg handler(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
        if(e instanceof ClientException) { //客户端异常(自定义异常)
            ClientException clientException = (ClientException) e;
            return clientException.getMsg();
        }else if(e instanceof MsgException) { //后台异常(自定义异常)
        	  MsgException msgException = (MsgException) e;
              return msgException.getMsg();
        }else if(e instanceof BindException) {//参数绑定校验异常
			BindException bindException = (BindException) e;
			if (bindException.hasErrors()) {
				return new Msg(bindException.getAllErrors().get(0).getDefaultMessage());
			}
        }
        e.printStackTrace();
        //系统其它的异常 全部统一返回
		return new Msg("系统服务开小差了,请稍后再试");
    }
}

用@ControllerAdvice定义的类中,也要写@ExceptionHandler标识的方法,出现异常时,就会执行@ExceptionHandler标识的方法。

1、方法出现异常时,@ExceptionHandler标记的方法的执行顺序

1)当一个类里面的方法出现异常时:先在该方法所在的类中找有没有@ExceptionHandler标记的方法,如果有,执行它

2)如果在当前类里面没有,就全局搜索看看有没有@ControllerAdvice标记的类,如果有,就执行该类里面@ExceptionHandler标记的方法。

2、自定义异常的创建

继承RuntimeException 就可以了,如:

public class ClientException extends RuntimeException {

	private Msg msg;

	public ClientException(Msg msg) {
		super(msg.getMsg());
		this.msg = msg;
	}

	public Msg getMsg() {
		return msg;
	}

	public void setMsg(Msg msg) {
		this.msg = msg;
	}
}

3、手动抛出自定义异常:

throw new ClientException(null);

猜你喜欢

转载自blog.csdn.net/java_xuetu/article/details/81741678