文档章节

@ControllerAdvice

o
 osc_wws45aot
发布于 2019/08/21 17:56
字数 880
阅读 0
收藏 0

钉钉、微博极速扩容黑科技,点击观看阿里云弹性计算年度发布会!>>>

在Spring 3.2中,新增了@ControllerAdvice、@RestControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping、@PostMapping, @GetMapping注解中。
接下来我将通过代码展示如何使用这些注解,以及处理异常。

1.注解的介绍

先定义一个ControllerAdvice。代码如下

/**
 * @author Lensen
 * @desc
 * @since 2018/10/5 11:01
 */
@ControllerAdvice
public 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<String, Object> customExceptionHandler(CustomException e) {
        Map<String, Object> 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<String, Object> 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
@Component
public @interface ControllerAdvice {
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<?>[] assignableTypes() default {};

    Class<? extends Annotation>[] annotations() default {};
}

 

 

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

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<String, Object> customExceptionHandler(CustomException e) {
        Map<String, Object> 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<String, Object> 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
 */
@Controller
public 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。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
spring的@ControllerAdvice注解

@ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理。 对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHan...

osc_f85py9gf
2019/05/15
8
0
SpringMVC之异常处理

@ExceptionHandler、@controlleradvice、HandlerExceptionResolver、ResponseEntityExceptionHandler、ErrorController 1.@ExceptionHandler注解 用于同一个 Controller 类下面方法异常捕获,......

红凯
2019/07/13
3
0
springboot 配置全局异常拦截

加全局异常处理之前的代码 @ControllerAdvice注解 配合使用注解 @ExceptionHandler @ModelAttribute @InitBinder 在Restful纯接口项目中,有@ControllerAdvice和@ExceptionHandler注解就够了...

Jetyang
2018/08/06
2.6K
0
公共请求及公共响应时的处理

利用@ControllerAdvice注解可以对请求的数据,及响应的数据做处理。 处理请求数据时:需要一个类实现RequestBodyAdvice接口,根据自己的需求,重写里面的方法,类需要用注解@ControllerAdvi...

1af7KLfkQ28UEDj2ttKn
2019/01/03
0
0
异常处理 java后端项目比较重要的一点

一、Controller局部异常处理 1.1. 使用示例 这种异常处理只局部于某个Controller内,如: 所有Controller方法(即被RequestMapping注解的方法)抛出的异常,会被该异常处理方法处理。 使用上...

edison_kwok
2019/11/03
20
0

没有更多内容

加载失败,请刷新页面

加载更多

SO_REUSEADDR和SO_REUSEPORT有何不同? - How do SO_REUSEADDR and SO_REUSEPORT differ?

问题: The man pages and programmer documentations for the socket options SO_REUSEADDR and SO_REUSEPORT are different for different operating systems and often highly confusing.......

法国红酒甜
今天
28
0
asp.net core之SignalR

SignalR 是什么? ASP.NET Core SignalR 是一个开源的实时框架,它简化了向应用中添加实时 Web 功能的过程。 实时 Web 功能是服务器端能够即时的将数据推送到客户端,而无需让服务器等待客户端...

一介草民Coder
今天
24
0
如何通过日期属性对数组进行排序 - How to sort an array by a date property

问题: Say I have an array of a few objects: 说我有一些对象的数组: var array = [{id: 1, date: Mar 12 2012 10:00:00 AM}, {id: 2, date: Mar 8 2012 08:00:00 AM}]; How can I sort......

javail
今天
22
0
技术教程| 百度鹰眼历史轨迹查询:轨迹抽稀功能

本文作者:用****9 本篇教程中,我们将详细地说明鹰眼历史轨迹查询(gettrack接口)中,如何通过vacuate_grade选项对轨迹进行抽稀,以及不同的抽稀力度对轨迹产生的影响。 上一篇教程中,我们...

百度开发者中心
前天
24
0
Quartz的Misfire处理规则 错过任务执行时间的处理机制

调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则 CronTrigger withMisfireHandlingInstructionDoNothing ——不触发立即执行 ——等待下次Cron触发频率...

独钓渔
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部