博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
精通Spring Boot —— 第十五篇:使用@ControllerAdvice处理异常
阅读量:6500 次
发布时间:2019-06-24

本文共 5289 字,大约阅读时间需要 17 分钟。

在Spring 3.2中,新增了@ControllerAdvice、@RestControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping、@PostMapping, @GetMapping注解中。

接下来我将通过代码展示如何使用这些注解,以及处理异常。

1.注解的介绍

先定义一个ControllerAdvice。代码如下

/** * @author Lensen * @desc * @since 2018/10/5 11:01 */@ControllerAdvicepublic class MyExceptionHandler {    /**     * 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器     * @param binder     */    @InitBinder    public void initWebBinder(WebDataBinder binder){        //对日期的统一处理        binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));        //添加对数据的校验        //binder.setValidator();    }    /**     * 把值绑定到Model中,使全局@RequestMapping可以获取到该值     * @param model     */    @ModelAttribute    public void addAttribute(Model model) {        model.addAttribute("attribute",  "The Attribute");    }    /**     * 捕获CustomException     * @param e     * @return json格式类型     */    @ResponseBody    @ExceptionHandler({CustomException.class}) //指定拦截异常的类型    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) //自定义浏览器返回状态码    public Map
customExceptionHandler(CustomException e) { Map
map = new HashMap<>(); map.put("code", e.getCode()); map.put("msg", e.getMsg()); return map; } /** * 捕获CustomException * @param e * @return 视图 */// @ExceptionHandler({CustomException.class})// public ModelAndView customModelAndViewExceptionHandler(CustomException e) {// Map
map = new HashMap<>();// map.put("code", e.getCode());// map.put("msg", e.getMsg());// ModelAndView modelAndView = new ModelAndView();// modelAndView.setViewName("error");// modelAndView.addObject(map);// return modelAndView;// }}

需要注意的是使用@ExceptionHandler注解传入的参数可以一个数组,且使用该注解时,传入的参数不能相同,也就是不能使用两个@ExceptionHandler去处理同一个异常。如果传入参数相同,则初始化ExceptionHandler时会失败。

对于@ControllerAdvice注解,我们来看看源码的定义:

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface ControllerAdvice {    @AliasFor("basePackages")    String[] value() default {};    @AliasFor("value")    String[] basePackages() default {};    Class
[] basePackageClasses() default {}; Class
[] assignableTypes() default {}; Class
[] annotations() default {};}

我们可以传递basePackage,声明的类(是一个数组)指定的Annotation参数,具体参考:

2.异常的处理

编写自定义异常类

package com.developlee.errorhandle.exception;/** * @author Lensen * @desc 自定义异常类 * @since 2018/10/5 11:04 */public class CustomException extends RuntimeException {    private long code;    private String msg;    public CustomException(Long code, String msg){        this.code = code;        this.msg = msg;    }    public long getCode() {        return code;    }    public void setCode(long code) {        this.code = code;    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;    }}

Spring 对于 RuntimeException类的异常才会进行事务回滚,所以我们一般自定义异常都继承该异常类。

编写全局异常处理类

/** * @author Lensen * @desc * @since 2018/10/5 11:01 */@ControllerAdvice("com.developlee.errorhandle")public class MyExceptionHandler {    /**     * 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器     * @param binder     */    @InitBinder    public void initWebBinder(WebDataBinder binder){    }    /**     * 把值绑定到Model中,使全局@RequestMapping可以获取到该值     * @param model     */    @ModelAttribute    public void addAttribute(Model model) {        model.addAttribute("attribute",  "The Attribute");    }    /**     * 捕获CustomException     * @param e     * @return json格式类型     */    @ResponseBody    @ExceptionHandler({CustomException.class}) //指定拦截异常的类型    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) //自定义浏览器返回状态码    public Map
customExceptionHandler(CustomException e) { Map
map = new HashMap<>(); map.put("code", e.getCode()); map.put("msg", e.getMsg()); return map; } /** * 捕获CustomException * @param e * @return 视图 */// @ExceptionHandler({CustomException.class})// public ModelAndView customModelAndViewExceptionHandler(CustomException e) {// Map
map = new HashMap<>();// map.put("code", e.getCode());// map.put("msg", e.getMsg());// ModelAndView modelAndView = new ModelAndView();// modelAndView.setViewName("error");// modelAndView.addObject(map);// return modelAndView;// }}

测试

在controller中抛出自定义异常

/** * @author Lensen * @desc * @since 2018/10/5 11:00 */@Controllerpublic class DemoController {      /**   * 关于@ModelAttribute,   * 可以使用ModelMap以及@ModelAttribute()来获取参数值。   */        @GetMapping("/one")    public String testError(ModelMap modelMap ) {        throw new CustomException(500L, "系统发生500异常!" + modelMap.get("attribute"));    }    @GetMapping("/two")    public String testTwo(@ModelAttribute("attribute") String attribute) {        throw new CustomException(500L, "系统发生500异常!" + attribute);    }}

启动应用,范围localhost:8080/one.返回报文为:

{"msg":"系统发生500异常!The Attribute","code":500}

可见我们的@InitBinder和@ModelAttribute注解生效。且自定义异常被成功拦截。如果全部异常处理都返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。@RestControllerAdvice在注解上已经添加了@ResponseBody。

最后,以上示例代码可在我的中找到。

我的个人公众号:developlee的潇洒人生。
关注了也不一定更新,更新就不得了了。
qrcode_for_gh_2bd3f44efa21_258

转载地址:http://fstyo.baihongyu.com/

你可能感兴趣的文章
硅谷顶级投资人看2017趋势,AI将成为5年前的“大数据”
查看>>
FPGA按一下按键,对应端口输出单个脉冲
查看>>
我为什么要写博客
查看>>
深度学习如何应用在广告、推荐及搜索业务?阿里妈妈实践案例解读
查看>>
科学家叫停机器人革命,请先思考背后的伦理问题
查看>>
Java基本语法
查看>>
泡沫里的无人机:看得很爽,一戳就破了
查看>>
Django | requirement.txt 生成
查看>>
UML类图关系大全
查看>>
真人版《美女与野兽》刚上映,迪士尼又推出同系列VR体验
查看>>
jquery图片查看插件,支持旋转、放大、缩小、拖拽、缩略图(仿qq图片查看)...
查看>>
Windows Azure 配置Active Directory 主机(3)
查看>>
四平方和
查看>>
SpringBoot 整合Redis 数据库
查看>>
中国首条工业4.0智能工厂示范线在深圳建成
查看>>
自动化设计-自动化测试环境搭建<一>
查看>>
Forrester报告:人工智能将取代6%的工作岗位
查看>>
SQL Server DBA 30问 【itpub】
查看>>
ipvsadm安装报错解决方法
查看>>
实现if elseif else的jsp标签。
查看>>