Spring3.2开始提供的新注解,控制器增强(AOP),最主要的应用是做统一的异常处理。@ControllerAdvice(看成spring mvc提供的一个特殊的拦截器)。

@ControllerAdvice是一个@Component,用于定义@ExceptionHandler(最主要用途),@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法(拦截)。

引申:@interface 元注解

@Target(ElementType.TYPE) :该注解应用到什么地方。

@Retention(RetentionPolicy.RUNTIME):什么时候应用。

@ExceptionHandler:为所有controller封装统一异常处理代码。

@ModelAttribute:为所有controller设置全局变量。

@InitBinder:用于为所有controller设置某个类型的数据转换器。

准备:搭建好Spring Boot,页面使用thymeleaf

1.全局异常捕捉处理

ControllerAdviceTest.java

/**

* 启动应用后,被 @ExceptionHandler、@InitBinder、@ModelAttribute 注解的方法,

* 都会作用在 被 @RequestMapping 注解的方法上

*/

@ControllerAdvice

public class ControllerAdviceTest {

/**

* 全局异常捕捉处理

* @ExceptionHandler 用来定义函数针对的异常类型

* @param ex

* @return

*/

@ResponseBody

@ExceptionHandler(value = Exception.class)

public Map errorHandler(Exception ex){

Map map = new HashMap();

map.put("code","0000");

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

return map;

}

}

ExceptionController.java

@RestController

public class ExceptionController {

@RequestMapping("exception1")

public String exception1() throws IOException {

return "拦截器测试";

}

}

浏览器访问:localhost:8080/exception1

浏览器显示:拦截器测试

@RestController

public class ExceptionController {

@RequestMapping("exception2")

public String exception2() throws IOException {

int i = 1/0;

return "拦截器测试";

}

}

浏览器访问:localhost:8080/exception2

浏览器显示:{"msg":"/ by zero","code":"0000"}

@RestController

public class ExceptionController {

@RequestMapping("exception3")

public String exception3() throws IOException {

throw new NullPointerException("服务器到非洲去了");

}

}

浏览器访问:localhost:8080/exception3

浏览器显示:{"msg":"服务器到非洲去了","code":"0000"}

2.拦截捕捉自定义异常

MyException.java

public class MyException extends RuntimeException {

private String code;

private String msg;

//Get、Set方法略……

public MyException(String code,String msg) {

this.code = code;

this.msg = msg;

}

}

ControllerAdviceTest.java

@ControllerAdvice

public class ControllerAdviceTest {

/**

* 拦截捕捉自定义异常 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;

}

}

ExceptionController.java

@RestController

public class ExceptionController {

@RequestMapping("myException")

public String myException(){

throw new MyException("1111","This is my Exception!");

}

}

浏览器访问:localhost:8080/myException

浏览器显示:{"msg":"This is my Exception!","code":"1111"}

跳转到一个单独的异常显示页面

ControllerAdviceTest.java

@ControllerAdvice

public class ControllerAdviceTest {

/**

* 跳转视图显示异常

* @param ex

* @return

*/

@ExceptionHandler(value = MyException.class)

public ModelAndView myErrorHandlerToView(MyException ex) {

ModelAndView modelAndView = new ModelAndView();

modelAndView.setViewName("myGlobalExceptionPage");

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

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

return modelAndView;

}

}

myGlobalExceptionPage.html

myGlobalExceptionPage

浏览器访问:localhost:8080/myException

浏览器显示:1111 This is my Exception!

3.绑定值到Model中

ControllerAdviceTest.java

@ControllerAdvice

public class ControllerAdviceTest {

/**

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

* @param model

*/

@ModelAttribute

public void addAttributes(Model model) {

System.out.println("添加全局变量");

model.addAttribute("userName", "Jack");

}

}

ExceptionController.java

@RestController

public class ExceptionController {

/**

* 使用注入的ModelMap来取变量

* @param modelMap

* @return

*/

@RequestMapping("modelMapTest1")

public Object modelMapTest1(ModelMap modelMap){

Object globalVal = modelMap.get("userName");

System.out.println("全局变量为:"+globalVal);

return globalVal;

}

}

浏览器访问:localhost:8080/modelMapTest1

控制台输出:添加全局变量 全局变量为:Jack

浏览器显示:Jack

ExceptionController.java

@RestController

public class ExceptionController {

/**

* 也可以使用@ModelAttribute注解来取变量

* @param globalVal

* @return

*/

@RequestMapping("/modelMapTest2")

public Object modelMapTest2(@ModelAttribute("userName") String globalVal) {

System.out.println("全局变量为:"+globalVal);

return globalVal;

}

}

浏览器访问:localhost:8080/modelMapTest2

控制台输出:添加全局变量 全局变量为:Jack

浏览器显示:Jack

4.转换日期格式

ControllerAdviceTest.java

@ControllerAdvice

public class ControllerAdviceTest {

/**

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

* WebDataBinder是用来绑定请求参数到指定的属性编辑器

* @param binder

*/

@InitBinder

public void initBinder(WebDataBinder binder) {

System.out.println("initBinder执行");

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

dateFormat.setLenient(false); //日期格式是否宽容(只能判断是否需要跳到下个月去)

/*

* spring mvc在绑定表单之前,都会先注册这些编辑器,

* Spring自己提供了大量的实现类,诸如CustomDateEditor,CustomBooleanEditor,CustomNumberEditor等

* 使用时候调用WebDataBinder的registerCustomEditor方法注册

*/

binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat,false));

}

}

ExceptionController.java

@RestController

public class ExceptionController {

@RequestMapping("/date")

public Date index(Date date){

System.out.println("date="+date);

return date;

}

}

浏览器访问:localhost:8080/date?date=2019-3-20

控制台输出:initBinder执行 date=2019-3-20

浏览器显示:"2019-3-20"

advice 和 拦截器_ControllerAdvice拦截器相关推荐

  1. jfinal js 拦截_jfinal 使用拦截器处理繁琐的前置条件判定

    使用拦截器处理繁琐的前置条件判定 背景 在开发过程中,为了提高程序的健壮性,对参数的校验是必不可少的,然而使用传统的方式进行参数校验时,导致程序中存在了if xxx return xxx;处理不够优雅 ...

  2. springboot拦截器拦截提示_Springboot拦截器使用及其底层源码剖析

    博主最近看了一下公司刚刚开发的微服务,准备入手从基本的过滤器以及拦截器开始剖析,以及在帮同学们分析一下上次的jetty过滤器源码与本次Springboot中tomcat中过滤器的区别.正题开始,拦截器 ...

  3. springmvc拦截器无法拦截jsp

    为什么80%的码农都做不了架构师?>>>    问题:spring mvc的拦截器只拦截controller不拦截jsp文件,如果不拦截jsp文件也会给系统带安全性问题. 解决方案: ...

  4. Struts2 自定义拦截器(方法拦截器)

    转自:http://05061107cm.iteye.com/blog/365504 struts2系统自带了很多拦截器,有时需要我们自己定义,一般有两种方式: 一.实现Interceptor接口 J ...

  5. axios 最全 请求拦截器 响应拦截器 配置公共请求头 超时时间 以及get delete post put 四种请求传参方式

    axios 拦截器 请求拦截器 请求拦截器的作用是在请求发送前进行一些操作 例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易 响应拦截器 响应拦截器的作用是在接收到响应后进行一些操 ...

  6. Struts2 拦截器: 拦截器与过滤器区别

    1.首先要明确什么是拦截器.什么是过滤器 1.1 什么是拦截器: 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加 ...

  7. Java web登录拦截器_SpringMVC拦截器(实现登录验证拦截器)

    本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 核心代码 首先是index.jsp,显示链接 String path = request.getContextPath(); String ...

  8. SpringMVC 视图解析器及拦截器

    视图解析器 跳转方式(设置返回值字符串内容) ①默认请求转发 forward:资源路径,forward可省略 ②重定向 redirect:资源路径 自定义视图解析器 SpringMVC会提供默认的视图 ...

  9. axios 请求拦截器响应拦截器

    一. 拦截器介绍 一般在使用axios时,会用到拦截器的功能,一般分为两种:请求拦截器.响应拦截器. 请求拦截器 在请求发送前进行必要操作处理,例如添加统一cookie.请求体加验证.设置请求头等,相 ...

最新文章

  1. python程序员在公司都是做什么的-为什么企业很难招聘到好的python程序员?
  2. sqlite3源码编译到Android,实现SQLite跨全平台使用
  3. Hdoj 1847.Good Luck in CET-4 Everybody! 题解
  4. flash 与数据库 图解
  5. C++类的前向声明的学习
  6. [转]SDI模式下,在视图中添加按钮
  7. C++ 友元函数 友元类 friend class
  8. c/c++再学习:C与Python相互调用
  9. paraview热流图(2):3D glyphs representation
  10. Java、JSP房产中介房屋信息管理系统
  11. Android CameraX的基本使用
  12. 百问网7天物联网智能家居(第七天)
  13. vue中axios的post请求url自动带上本地ip解决方法
  14. php强类型作用,强类型php性能很彪悍
  15. 删除在计算机的没用东西,怎么删除电脑中没用的东西?
  16. 水果店节日活动营销方案,水果店如何做营销活动
  17. 【新闻】微信出现大面积BUG!腾讯紧急回应!
  18. 传软银COO即将离职,孙正义痛失得力助手,或因20亿美元薪酬
  19. AES解密控制台中文乱码问题
  20. Oracle-09:聚合函数

热门文章

  1. android微信调试网页,Mac OS X EI Capitan 下调试 Android 微信内嵌网页
  2. 一文详解MySQL中的事件调度器EVENT
  3. 前沿 | VLDB 2019论文解读:阿里巴巴大规模数据库智能参数优化的创新与实践
  4. 玩转LiteOS组件:玩转Librws
  5. 看FusionInsight Spark如何支持JDBCServer的多实例特性
  6. 【万字长文】探讨可信构架之道
  7. 从需求到交付——论敏捷过程中的需求管理
  8. #华为云·寻找黑马程序员#【代码重构之路】如何“消除”if/else
  9. android实现截图功能吗,Android实现拍照截图功能
  10. Vue深入学习1—mustache模板引擎原理