【Spring】Spring全局异常处理(二)

Spring全局异常处理

Spring全局异常处理(一).

@ControllerAdvice和@ExceptionHandler

从源码的介绍里可以大概的总结如下:

  • 一个注解了ControllerAdvice的类。可以定义@ExceptionHandler、@InitBinder、@ModelAttribute的方法。这样的类可以处理@Controller抛出来的异常
  • 可以通过注解@Order、@Priority或者实现Ordered接口定义优先级
  • 对于@ExceptionHandler的方法,处理异常的顺序是:优先级更高的类>异常的父类的处理方法>异常本身的处理方法
  • 默认地,@ControllerAdvice的方法适用于所有的controllers.可以通过annotations、basePackageClasses、basePackages、value、assignableTypes指定相应的controllers。如果多个同时指定,只要满足其中一个即可

定义

使用@ControllerAdvice@ExceptionHandler组合可以处理controller抛出来的异常。例子实践一下。

异常处理

@ControllerAdvice
public class ControllerAdviceExample {
    
    @ExceptionHandler(value = { ClassNotFoundException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put("message", "@ControllerAdvice & @ExceptionHandler handle exception!!!!!!!!!!!");
      return resultMap;
    }
}

控制器

@RestController
@RequestMapping("controllerAdvice")
public class ControllerAdviceController {
    @GetMapping
    public String handleException() throws Exception {
        throw new ClassNotFoundException("--------handleException----------");
    }
}

运行起来后访问/controllerAdvice得到如下结果:

请添加图片描述

证明我们定义的全局异常处理起作用了。

Order

可以通过注解@link org.springframework.core.annotation.Order @Order@link javax.annotation.Priority @Priority或者实现@link org.springframework.core.Ordered Ordered接口定义优先级

我们定义两个ControllerAdvice类,分别用@Order定义优先顺序。

@Order(1)

@ControllerAdvice
// 定义优先级
@Order(1)
public class ControllerAdviceOrder1 {
  
    @ExceptionHandler(value = { ClassNotFoundException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
        return resultMap;
    }
}

@Order(2)

@ControllerAdvice
// 定义优先级
@Order(2)
public class ControllerAdviceOrder2 {
    
    @ExceptionHandler(value = { ClassNotFoundException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
      return resultMap;
    }
}

重新启动程序后访问/controllerAdvice得到如下结果:
请添加图片描述

@Order的值越小优先级越高,@Priority的使用方法和@Order是一样的,接下来我们看看如何实现Ordered接口定义优先级

优先级为1的实现

@ControllerAdvice
public class ControllerAdviceOrdered1 implements Ordered{
  
    @ExceptionHandler(value = { ClassNotFoundException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
        return resultMap;
    }

    // 实现该函数,返回优先级的数值
    @Override
    public int getOrder() {
        return 1;
    }
}

优先级为2的实现

@ControllerAdvice
public class ControllerAdviceOrdered2 implements Ordered {
    
    @ExceptionHandler(value = { ClassNotFoundException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response,
            Exception ex) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
        return resultMap;
    }
    
    // 实现该函数,返回优先级的数值
    @Override
    public int getOrder() {
        return 2;
    }
}

启动程序后访问/controllerAdvice得到如下结果:

请添加图片描述

接口Ordered通过实现getOrder函数实现优先级的赋值。

实现接口PriorityOrdered的类优先级低于实现了接口Ordered的类

Ordered定义优先级为1的ControllerAdvice

@ControllerAdvice
public class ControllerAdviceOrdered1 implements Ordered {
    
    @ExceptionHandler(value = { ClassNotFoundException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response,
            Exception ex) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
        return resultMap;
    }
    
    // 实现该函数,返回优先级的数值
    @Override
    public int getOrder() {
        return 1;
    }
}

ControllerAdvicePriorityOrdered定义优先级为2的ControllerAdvice

@ControllerAdvice
public class ControllerAdvicePriorityOrdered implements PriorityOrdered{
    @ExceptionHandler(value = { ClassNotFoundException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ResponseBody
    public Map<String, Object> controllerAdvice(HttpServletRequest request, HttpServletResponse response,
            Exception ex) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("message", getClass().getName() + " handles exception!!!!!!!!!!!");
        return resultMap;
    }
    
    // 实现该函数,返回优先级的数值
    @Override
    public int getOrder() {
        return 1;
    }
}

启动程序后访问/controllerAdvice得到如下结果:

请添加图片描述

虽然都定义了优先级为1,但是会先调用Ordered的实现。

未完待续

蜗牛速度般的学习,慢牛般的成长-

​更多文章欢迎关注“三横兰”

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值