博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
@ControllerAdvice 拦截异常并统一处理
阅读量:5833 次
发布时间:2019-06-18

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

hot3.png

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

一、介绍

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

package com.sam.demo.controller;import org.springframework.ui.Model;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.InitBinder;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.ResponseBody;import java.util.HashMap;import java.util.Map;/** * controller 增强器 */@ControllerAdvicepublic class MyControllerAdvice {    /**     * 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器     *     * @param binder     */    @InitBinder    public void initBinder(WebDataBinder binder) {    }    /**     * 把值绑定到Model中,使全局@RequestMapping可以获取到该值     *     * @param model     */    @ModelAttribute    public void addAttributes(Model model) {        model.addAttribute("author", "Magical Sam");    }    /**     * 全局异常捕捉处理     *     * @param ex     * @return     */    @ResponseBody    @ExceptionHandler(value = Exception.class)    public Map errorHandler(Exception ex) {        Map map = new HashMap();        map.put("code", 100);        map.put("msg", ex.getMessage());        return map;    }}

    启动应用后,添加了@ExceptionHandler、@InitBinder、@ModelAttribute 注解的方法,都会作用于添加@RequestMapping 注解的方法之上。

 

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

//通过modelMap.get()获取@RequestMapping("/home")public String home(ModelMap modelMap){    System.out.println(modelMap.get("author"));}//通过@ModelAttribute获取@RequestMapping("/home")public String home(@ModelAttribute("author") String author){    System.out.println(author);}

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

 

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

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

1.编写自定义异常类:

package com.demo.custom;public class MyException extends RuntimeException {	public MyException(String code, String msg) {		this.code = code;		this.msg = msg;	}	private String code;	private String msg;	// getter & setter}

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

2、编写全局异常处理类

    创建 MyControllerAdvice.java:

package com.sam.demo.controller;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import java.util.HashMap;import java.util.Map;@ControllerAdvicepublic class MyControllerAdvice {    /**     * 全局异常捕捉处理     *     * @param ex     * @return     */    @ResponseBody    @ExceptionHandler(value = Exception.class)    public Map errorHandler(Exception ex) {        Map map = new HashMap();        map.put("code", 100);        map.put("msg", ex.getMessage());        return map;    }    /**     * 拦截捕捉自定义异常 MyException.class     *     * @param ex     * @return     */    @ResponseBody    @ExceptionHandler(value = MyException.class)    public Map myErrorHandler(MyException ex) {        Map map = new HashMap();        map.put("code", ex.getCode());        map.put("msg", ex.getMsg());        return map;    }}

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

@RequestMapping("/home")public String home() throws Exception {   //throw new Exception("Sam 错误");   throw new MyException("101", "Sam 错误");}

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

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

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

@ExceptionHandler(value = MyException.class)public ModelAndView myErrorHandler(MyException ex) {    ModelAndView modelAndView = new ModelAndView();    modelAndView.setViewName("error");    modelAndView.addObject("code", ex.getCode());    modelAndView.addObject("msg", ex.getMsg());    return modelAndView;}

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

    
错误页面

${code}

${msg}

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

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

转载于:https://my.oschina.net/langwanghuangshifu/blog/2246890

你可能感兴趣的文章
BZOJ 1342: [Baltic2007]Sound静音问题 [单调队列]
查看>>
小米王川:我与雷军和而不同
查看>>
数据结构--队列
查看>>
JavaScript中的call和apply应用
查看>>
SpringBoot中Redis的set、map、list、value、实体类等基本操作介绍
查看>>
Android OpenGL ES 开发(三): OpenGL ES 定义形状
查看>>
Linux防止“rm -rf /”误删除
查看>>
python用matplotlib画折线图
查看>>
时钟制作代码
查看>>
postgresql某进程占用cpu资源过高,降不下来
查看>>
php实现 句子逆序(需求才是最好的老师)
查看>>
Android Studio占用C盘内存
查看>>
C# 有道API翻译 查询单词详细信息
查看>>
观察者模式之一:java实现观察者模式
查看>>
数据库设计 Step by Step (1)
查看>>
利用 LDAP 目录查看插件扩展 Lotus Sametime 客户机
查看>>
如何在一个进程中启动另外一个线程:ProcessStartInfo Constructor
查看>>
完全卸载 QuickTest Professional 10
查看>>
精美LOGO设计欣赏的200佳网站推荐(系列十四)
查看>>
框架学习之Spring 第一节 认识Spring以及环境的配置
查看>>