SpringMVC 全局异常统一处理

SpringMVC 异常统一处理的三种方式:

  1. 使用 @ExceptionHandler 注解
  2. 实现 HandlerExceptionResolver 接口
  3. 使用 @ControllerAdvice 注解

总结

当以上三个方式,一起出现时,只执行执行范围最小的方式,后面的方式不再执行处理;

执行范围:@ExceptionHandler < @ControllerAdvice+@E..Handler < HandlerExceptionResolver

人话:当某个Mapping方法发生异常后,先由@ExceptionHandler 处理;如果没有上者,则由@ControllerAdvice+@E..Handler 处理;如果没有上者 则由 HandlerExceptionResolver 处理

  • 使用 @ExceptionHandler 注解

作用域:局部,针对一个Controller中的指定异常类;

注有该注解的方法,和发生异常的Mapping方法,两者需要在同一个Controller里;

@Controller
@ResponseBody
public class Cors {
    @RequestMapping("/cors")
    public String reqShow(HttpServletRequest request){
        // 发生 ArithmeticException 异常
        int i = 1/0;
        // 是否是 Ajax 请求
        return "XMLHttpRequest".
            equalsIgnoreCase(request.getHeader("X-Requested-With"));
    }
	// @ExceptionHandler 参数为 要处理器的 异常类(或子类)
    @ExceptionHandler(ArithmeticException.class)
    public String exInfo(ArithmeticException e){
        System.out.println(e.getMessage());
        return "seccess";
    }
}
  • 实现 HandlerExceptionResolver 接口

作用域:全局,针对全部Controller,无需指定某个异常类;

HandlerExceptionResolver 接口 中 只有 resolveException 一个方法,实现即可;

@Component
public class HandlerEx implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
                                         HttpServletResponse httpServletResponse, Object o, Exception e) {
        System.out.println(e.getMessage());
        return null;
    }
}
  • 使用 @ControllerAdvice 注解

作用域:全局,针对全部Controller中的指定异常类;

该注解需要 和@ExceptionHandler配合,来完成全局异常的处理;

注意:两个注解的配合,发生异常Mapping方法 与 @ExceptionHandler注解的方法 就可以不用写在同一个Controller 里;

@Controller
@ResponseBody
public class Cors {
    @RequestMapping("/cors")
    public String reqShow(){
        // 发生 ArithmeticException 异常 
        int i = 1/0;
        return "hello";
    }
}

@ControllerAdvice
public class AppAllException{
    @ResponseStatus(HttpStatus.BAD_REQUEST)	// 响应 状态码400
    // @ExceptionHandler 参数为 要处理器的 异常类(或子类) 
    // 注解参数不声明指定异常类,则默认为方法列表中的异常参数类
    @ExceptionHandler(ArithmeticException.class)
    public void showInfo(Exception e){
        System.out.println(e.getMessage());
    }
}

此时,依然坚持写在同一个Controler里的话,未尝不可。不改变的是:作用域仍是全局的;例子如下

@Controller
@ControllerAdvice
public class ShiroAllException {
    @RequestMapping("/cors")
    public String reqShow(){
        int i = 1/0;
        return "hello";
    }
    
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ArithmeticException.class)
    public void showInfo(Exception e){
        System.out.println(e.getMessage());
    }
}
posted @ 2020-03-20 16:06  花中手  阅读(2813)  评论(0编辑  收藏  举报