SpringMVC重要注解 @ControllerAdvice
@ControllerAdvice
,是Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强。让我们先看看@ControllerAdvice
的实现:
package org.springframework.web.bind.annotation; @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 {};
}
没什么特别之处,该注解使用@Component
注解,这样的话当我们使用<context:component-scan>
扫描时也能扫描到。
再一起看看官方提供的comment。
大致意思是:
@ControllerAdvice
是一个@Component
,用于定义@ExceptionHandler
,@InitBinder
和@ModelAttribute
方法,适用于所有使用@RequestMapping
方法。Spring4之前,
@ControllerAdvice
在同一调度的Servlet中协助所有控制器。Spring4已经改变:@ControllerAdvice
支持配置控制器的子集,而默认的行为仍然可以利用。在Spring4中,
@ControllerAdvice
通过annotations()
,basePackageClasses()
,basePackages()
方法定制用于选择控制器子集。
不过据经验之谈,只有配合@ExceptionHandler
最有用,其它两个不常用。
在SpringMVC重要注解(一)@ExceptionHandler
和@ResponseStatus
我们提到,如果单使用@ExceptionHandler
,只能在当前Controller中处理异常。但当配合@ControllerAdvice
一起使用的时候,就可以摆脱那个限制了。
package com.somnus.advice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice
public class ExceptionAdvice { @ExceptionHandler({ ArrayIndexOutOfBoundsException.class })
@ResponseBody
public String handleArrayIndexOutOfBoundsException(Exception e) {
e.printStackTrace();
return "testArrayIndexOutOfBoundsException";
@Controller
@RequestMapping(value = "exception")
public class ExceptionHandlerController { @RequestMapping(value = "e2/{id}", method = { RequestMethod.GET })
@ResponseBody
public String testExceptionHandle2(@PathVariable(value = "id") Integer id) {
List<String> list = Arrays.asList(new String[]{"a","b","c","d"});
return list.get(id-1);
} }
当我们访问http://localhost:8080/SpringMVC/exception/e2/5
的时候会抛出ArrayIndexOutOfBoundsException
异常,这时候定义在@ControllerAdvice
中的@ExceptionHandler
就开始发挥作用了。
如果我们想定义一个处理全局的异常
package com.somnus.advice; import javax.servlet.http.HttpServletRequest; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice
public class ExceptionAdvice { @ExceptionHandler({ Exception.class })
@ResponseBody
public String handException(HttpServletRequest request ,Exception e) throws Exception {
e.printStackTrace(); return e.getMessage();
}
}
乍一眼看上去毫无问题,但这里有一个纰漏,由于Exception
是异常的父类,如果你的项目中出现过在自定义异常中使用@ResponseStatus
的情况,你的初衷是碰到那个自定义异常响应对应的状态码,而这个控制器增强处理类,会首先进入,并直接返回,不会再有@ResponseStatus
的事情了,这里为了解决这种纰漏,我提供了一种解决方式。
package com.somnus.advice; import javax.servlet.http.HttpServletRequest; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice
public class ExceptionAdvice { @ExceptionHandler({ Exception.class })
@ResponseBody
public String handException(HttpServletRequest request ,Exception e) throws Exception {
e.printStackTrace();
//If the exception is annotated with @ResponseStatus rethrow it and let
// the framework handle it - like the OrderNotFoundException example
// at the start of this post.
// AnnotationUtils is a Spring Framework utility class.
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null){
throw e;
}
// Otherwise setup and send the user to a default error-view.
/*ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", request.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;*/
return e.getMessage();
} }
如果碰到了某个自定义异常加上了@ResponseStatus
,就继续抛出,这样就不会让自定义异常失去加上@ResponseStatus
的初衷。
SpringMVC重要注解 @ControllerAdvice的更多相关文章
- SpringMVC异常处理注解@ExceptionHandler@ControllerAdvice@ResponseStatus
参考: http://blog.csdn.net/w372426096/article/details/78429132 http://blog.csdn.net/w372426096/article ...
- Spring3.2新注解@ControllerAdvice
Spring3.2新注解@ControllerAdvice @ControllerAdvice,是spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强.让我们先看看@Control ...
- springBoot注解大全JPA注解springMVC相关注解全局异常处理
https://www.cnblogs.com/tanwei81/p/6814022.html 一.注解(annotations)列表 @SpringBootApplication:包含了@Compo ...
- Spring 和 SpringMVC 常用注解和配置(@Autowired、@Resource、@Component、@Repository、@Service、@Controller的区别)
Spring 常用注解 总结内容 一.Spring部分 1.声明bean的注解 2.注入bean的注解 3.java配置类相关注解 4.切面(AOP)相关注解 5.事务注解 6.@Bean的属性支持 ...
- SpringMVC常用注解實例詳解3:@ResponseBody
我的開發環境框架: springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...
- SpringMVC常用注解實例詳解2:@ModelAttribute
我的開發環境框架: springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...
- springMVC的注解详解
springmvc常用注解标签详解 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业 ...
- springmvc常用注解与类型转换
springmvc常用注解与类型转换 一:前置 spring -servlet.xml 注入 <!-- 启用spring mvc 注解 --> <context:annotation ...
- springMvc的注解注入方式
springMvc的注解注入方式 最近在看springMvc的源码,看到了该框架的注入注解的部分觉的有点吃力,可能还是对注解的方面的知识还认识的不够深刻,所以特意去学习注解方面的知识.由于本人也是抱着 ...
随机推荐
- [PHP] 使用ftell和fseek函数直接定位文件位置获取部分数据
对于大文件只获取部分数据很有用 1.使用ftell函数可以获取当前指针的字节位置2.使用fseek函数可以直接定位到指定的位置3.读取指定字节的数据就可以部分获取文件内容了 <?php clas ...
- JS高阶---变量与函数提升
大纲: 主体: 案例1: 接下来在控制台source里进行断点测试 打好断点后,在控制台测试window .
- 代码审计-extract变量覆盖
<?php $flag='xxx'; extract($_GET); if(isset($shiyan)) { $content=trim(file_get_contents($flag)); ...
- springboot常见问题
什么是 Spring Boot? 为什么要用 Spring Boot? Spring Boot 的核心配置文件有哪几个?它们的区别是什么? Spring Boot 的配置文件有哪几种格式?它们有什么区 ...
- MySQL数据库 存储引擎,创建表完整的语法,字段类型,约束条件
1.存储引擎 - 存储引擎是用于根据不同的机制处理不同的数据. - 查看mysql中所有引擎: - show engines; - myisam: 5.5以前老的版本使用的存储引擎 - blackho ...
- Provider和Consumer的搭建(六)
创建三个Maven Project: dubbo-service:公共模块,包括服务接口(packaging:jar) dubbo-service-impl:服务提供方,提供服务接口的具体实现,需要依 ...
- 13 opencv训练器
https://blog.csdn.net/WZZ18191171661/article/details/91305466 https://blog.csdn.net/qq_25352981/arti ...
- Python爬虫爬取数据的步骤
爬虫: 网络爬虫是捜索引擎抓取系统(Baidu.Google等)的重要组成部分.主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份. 步骤: 第一步:获取网页链接 1.观察需要爬取的多 ...
- Linux性能优化实战学习笔记:第四十七讲
一.上节回顾 上一节,我们梳理了,应用程序容器化后性能下降的分析方法.一起先简单回顾下.容器利用 Linux 内核提供的命名空间技术,将不同应用程序的运行隔离起来,并用统一的镜像,来管理应用程序的依赖 ...
- WEB前端开发职业学习路线初级完整版
作者 | Jeskson 来源 | 达达前端小酒馆 下面小编专门为广大web前端开发职业者汇总了学习路线初级完整版,其实web前端开发工程师可算是高福利,高薪水的职业了,所以现在学习web前端开发的技 ...