【SpringMVC应用篇】SpringMVC自定义异常处理

【SpringMVC应用篇】SpringMVC自定义异常处理

@ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理。最常用的就是异常处理

@ModelAttribute@ExceptionHandler,前者可以往请求的Model里加数据,后者可以接受请求处理方法抛出的异常。但是他们放在控制器(Controller)里的时候,作用范围是有限的,只管当前控制器里的方法。如果你有几百个控制器,在每个控制器里都加上类似的代码,不免有点冗余和费劲儿。Spring框架提供了@ControllerAdvice注解,帮助你将其应用到所有的控制器上。

Controller Advice字面上意思是“控制器通知”,Advice除了“劝告”、“意见”之外,还有“通知”的意思。你可以将@ModelAttribute@ExceptionHandler标记的方法提取出来,放到一个类里,并将加上@ControllerAdvice,这样,所有的控制器都可以用了:

@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 应用到所有@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",  "理解万岁!!!");
    }
}

controller中获取:
1、可以使用ModelMap以及@ModelAttribute()来获取参数值。
2、@ModelAttribute(“attribute”) 注解获取参数值

@Controller
public class ExceptionTestController {

    /**
     * 关于@ModelAttribute,
     * 1、可以使用ModelMap以及@ModelAttribute()来获取参数值。
     */
    @GetMapping("/one")
    public String testError(ModelMap modelMap ) {
        String attribute = (String)modelMap.get("attribute");
    }

    /**
     * 2、@ModelAttribute("attribute") 注解获取参数值
     */
    @GetMapping("/two")
    public String testTwo(@ModelAttribute("attribute") String attribute) {
        System.out.println(attribute);
    }
}

因为@ControllerAdvice被元注解@Component标记,所以它也是可以被组件扫描扫到并放入Spring容器的。
在这里插入图片描述

如果你只想对一部分控制器添加通知,比如某个包下的控制器,可以这样写:

在这里插入图片描述

如果你不想把包名写死,不如把包里的某个类传进去,这样包名重构了也不怕:

在这里插入图片描述

通知里的@ModelAttribute方法会先于控制器里执行。通知里的@ExceptionHandler方法优先级会低于控制器里的。

控制器通知还有一个兄弟,@RestControllerAdvice,如果用了它,错误处理方法的返回值不会表示用的哪个视图,而是会作为HTTP body处理,即相当于错误处理方法加了@ResponseBody注解。

统一异常处理

需要配合@ExceptionHandler使用。当将异常抛到controller时,可以对异常进行统一处理,规定返回的json格式或是跳转到一个错误页面,如果都放回JSON格式的数据可以使用@RestControllerAdvice

@ControllerAdvice()
public class GlobalExceptionHandler {

    /**
     * 应用到所有@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",  "理解万岁!!!");
    }

    /**
     * 捕获CustomException
     * @param e
     * @return json格式类型  @RestControllerAdvice
     */
    @ResponseBody
    @ExceptionHandler({CustomException.class}) //指定拦截异常的类型
    @ResponseStatus(HttpStatus.NOT_FOUND) //自定义浏览器返回状态码
    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;
//    }
}

定义异常类对象

//自定义异常类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CustomException extends RuntimeException {
    private long code;
    private String msg;
}

controller中测试

@Controller
public class ExceptionTestController {

    /**
     * 关于@ModelAttribute,
     * 1、可以使用ModelMap以及@ModelAttribute()来获取参数值。
     */
    @GetMapping("/one")
    public String testError(ModelMap modelMap ) {
        String attribute = (String)modelMap.get("attribute");
        throw new CustomException(123L, "系统发生500异常!=====获取全局ModelMap参数值:" + modelMap.get("attribute"));
    }

    /**
     * 2、@ModelAttribute("attribute") 注解获取参数值
     */
    @GetMapping("/two")
    public String testTwo(@ModelAttribute("attribute") String attribute) {
        System.out.println(attribute);
        throw new CustomException(324L, "系统发生500异常!=====获取全局ModelMap参数值:" + attribute);
    }
}

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李熠漾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值