美文网首页
@ControllerAdvice 和 @RestControl

@ControllerAdvice 和 @RestControl

作者: 蓝色Hippie | 来源:发表于2020-06-24 16:34 被阅读0次

    **https://blog.csdn.net/scdncby/article/details/89645457

    在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。参考:@ControllerAdvice 文档

    一、介绍

    创建 MyControllerAdvice,并添加 @ControllerAdvice注解。

    packagecom.sam.demo.controller;

    importorg.springframework.ui.Model;

    importorg.springframework.web.bind.WebDataBinder;

    importorg.springframework.web.bind.annotation.*;

    importjava.util.HashMap;

    importjava.util.Map;

    /**

    • controller 增强器

    *@authorsam

    *@since2017/7/17

    */

    @ControllerAdvice

    publicclassMyControllerAdvice{

    /**

    • 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器

    *@parambinder

    */
    

    @InitBinder

    publicvoidinitBinder(WebDataBinder binder){}

    /**

    • 把值绑定到Model中,使全局@RequestMapping可以获取到该值

    *@parammodel

    */
    

    @ModelAttribute

    publicvoidaddAttributes(Model model){

    model.addAttribute("author","Magical Sam");

    }
    

    /**

    * 全局异常捕捉处理
    

    *@paramex

    *@return

    */
    

    @ResponseBody

    @ExceptionHandler(value = Exception.class)

    publicMaperrorHandler(Exception ex){

    Map map =newHashMap();

    map.put("code",100);

    map.put("msg", ex.getMessage());

    returnmap;

    }
    

    }

    启动应用后,被 @ExceptionHandler、@InitBinder、@ModelAttribute 注解的方法,都会作用在 被 @RequestMapping 注解的方法上。

    @ModelAttribute:在Model上设置的值,对于所有被 @RequestMapping 注解的方法中,都可以通过 ModelMap 获取,如下:

    @RequestMapping("/home")

    publicString home(ModelMap modelMap) {

    System.out.println(modelMap.get("author"));

    }

    //或者 通过@ModelAttribute获取

    @RequestMapping("/home")

    publicString home(@ModelAttribute("author")String author) {

    System.out.println(author);

    }

    @ExceptionHandler 拦截了异常,我们可以通过该注解实现自定义异常处理。其中,@ExceptionHandler 配置的 value 指定需要拦截的异常类型,上面拦截了 Exception.class 这种异常。

    二、自定义异常处理(全局异常处理)

    spring boot 默认情况下会映射到 /error 进行异常处理,但是提示并不十分友好,下面自定义异常处理,提供友好展示。

    1、编写自定义异常类:

    packagecom.sam.demo.custom;

    /**

    *@authorsam

    *@since2017/7/17

    */

    publicclassMyExceptionextendsRuntimeException{

    publicMyException(String code, String msg){

    this.code = code;

    this.msg = msg;

    }
    

    privateString code;

    privateString msg;

    // getter & setter

    }

    注:spring 对于 RuntimeException 异常才会进行事务回滚。

    2、编写全局异常处理类

    创建 MyControllerAdvice.java,如下:

    package com.sam.demo.controller;

    importorg.springframework.ui.Model;

    importorg.springframework.web.bind.WebDataBinder;

    importorg.springframework.web.bind.annotation.*;

    importjava.util.HashMap;

    importjava.util.Map;

    /**

    • controller 增强器

    • @author sam

    • @since 2017/7/17

    */

    @ControllerAdvice

    publicclassMyControllerAdvice{

    /**

    * 全局异常捕捉处理
    
    * @param ex
    
    * @return
    
    */
    

    @ResponseBody

    @ExceptionHandler(value =Exception.class)

    publicMaperrorHandler(Exceptionex) {

    Mapmap= newHashMap();

    map.put("code",100);

    map.put("msg", ex.getMessage());

    returnmap;

    }
    

    /**

    * 拦截捕捉自定义异常 MyException.class
    
    * @param ex
    
    * @return
    
    */
    

    @ResponseBody

    @ExceptionHandler(value =MyException.class)

    publicMapmyErrorHandler(MyExceptionex) {

    Mapmap= newHashMap();

    map.put("code", ex.getCode());

    map.put("msg", ex.getMsg());

    returnmap;

    }
    

    }

    3、controller中抛出异常进行测试。

    @RequestMapping("/home")

    publicStringhome()throwsException{

    // throw new Exception("Sam 错误");

    thrownewMyException("101","Sam 错误");

    }

    启动应用,访问:http://localhost:8080/home ,正常显示以下json内容,证明自定义异常已经成功被拦截。

    {"msg":"Sam 错误","code":"101"}

    • 如果不需要返回json数据,而要渲染某个页面模板返回给浏览器,那么MyControllerAdvice中可以这么实现:

    @ExceptionHandler(value = MyException.class)

    publicModelAndViewmyErrorHandler(MyException ex){

    ModelAndView modelAndView =newModelAndView();

    modelAndView.setViewName("error");

    modelAndView.addObject("code", ex.getCode());

    modelAndView.addObject("msg", ex.getMsg());

    returnmodelAndView;

    }

    在 templates 目录下,添加 error.ftl(这里使用freemarker) 进行渲染:

    <!DOCTYPE html>

    错误页面

    ${code}

    ${msg}

    重启应用,http://localhost:8080/home 显示自定的错误页面内容。

    补充:如果全部异常处理返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。

    相关文章

      网友评论

          本文标题:@ControllerAdvice 和 @RestControl

          本文链接:https://www.haomeiwen.com/subject/nwwkactx.html