SpringBoot - @ControllerAdvice注解详解

spring注解@ControllerAdvice的原理分析和使用 @ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理。 对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不止于此。ControllerAdvice拆开来就是Controller Advice,关于Advice,在Spring的AOP中,是用来封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ControllerA 阅读详情

写在前面

@RestControllerAdvice = @ControllerAdvice + @ResponseBody
@ControllerAdvice 就是 @Controller 的增强版。@ControllerAdvice 主要用来处理全局数据,一般搭配 @ExceptionHandler、@ModelAttribute、@InitBinder使用,在三个应用场景中使用:全局异常处理、全局数据绑定和全局数据预处理。@ControllerAdvice是@Component注解的一个延伸注解,Spring会自动扫描并能检测到被@ControllerAdvice所标注的类。

SpringBoot - @RequestBody、@ResponseBody的使用场景

应用范围

适用于所有的@RequestMapping标注的方法上,也就是说该注解应该添加在被@RestController/@Controller注解标注的类中的方法上。

场景1:与@ExceptionHandler注解组合使用,完成全局异常处理

使用总结

A. 创建一个全局异常类;
B. 在该全局异常类上添加注解:@ControllerAdvice;
C. 在该全局异常类中定义"方法1",并添加注解:@ExceptionHandler(AccessDeniedException.class);
其中定义的 AccessDeniedException.class 表明该"方法1"用来处理 AccessDeniedException类型的异常。
D. 在该全局异常类中定义"方法2",并添加注解:@ExceptionHandler(Exception.class);
表明该"方法2"用来处理所有类型的异常。
E. 在该全局异常类中定义的方法的参数,可以是异常类的实例、HttpServletResponse、HttpServletRequest或者Model 等;
F. 在该全局异常类中定义的方法的返回值可以是一段 JSON、一个 ModelAndView、一个逻辑视图名等等;
G. @ControllerAdvice可以指定扫描路径:@ControllerAdvice(basePackages={“cn.hadoopx.system”, “cn.hadoopx.common”})

优缺点

优点:将Controller层的异常和数据校验的异常进行统一处理,减少模板try-catch的代码,减少编码量,提升扩展性和可维护性。
缺点:只能处理Controller层未捕获的异常,无法捕获拦截器层和SPRING框架层的异常。

示例代码
/**
 * 全局异常处理器
 *
 * @author ROCKY
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 权限校验异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public Result handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
        return Result.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                          HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return Result.error(e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(ServiceException.class)
    public Result handleServiceException(ServiceException e, HttpServletRequest request) {
        log.error(e.getMessage(), e);
        Integer code = e.getCode();
        return StringUtils.isNotNull(code) ? 
        Result.error(code, e.getMessage()) : Result.error(e.getMessage());
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public Result handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常.", requestURI, e);
        return Result.error(e.getMessage());
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURI, e);
        return Result.error(e.getMessage());
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(BindException.class)
    public Result handleBindException(BindException e) {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return Result.error(message);
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return Result.error(message);
    }

    /**
     * 演示模式异常
     */
    @ExceptionHandler(DemoModeException.class)
    public Result handleDemoModeException(DemoModeException e) {
        return Result.error("演示模式,不允许操作");
    }
}

场景2:与@ModelAttribute注解组合使用,完成全局数据绑定

使用总结

全局数据绑定可以用来做一些初始化数据的操作,可以将一些公共的数据定义在添加了@ControllerAdvice注解的类中,这样的话每个Controller接口都能访问这些数据。
A. 使用@Model Attribute 注解标记的方法,返回数据是一个全局数据;
B. @ModelAttribute(value = “looker”), 其中 value 属性表示这条返回数据的KEY,而方法的返回值是返回数据的VALUE。

示例代码
@ControllerAdvice
public class TheLooker{
	// 方式1
    @ModelAttribute(value  = "looker")
    public Map<String, String> globalData() {
        HashMap<String, String> map = new HashMap<>();
        map.put("name", "ROCKY");
        map.put("age", "30");
        map.put("info", "rich");
        return map;
    }
    // 方式2, @ModelAttribute也可以不写value参数,直接在方法中对全局Model设置key和value
	@ModelAttribute
    public void addAttributes(Model model) {
        HashMap<String, String> map = new HashMap<>();
        map.put("name", "ROCKY");
        map.put("age", "30");
        map.put("info", "rich");
        model.addAttribute("looker", map);
    }
}

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(Model model) {
        Map<String, Object> map = model.asMap();
        // 获取全局数据
        Map<String, String> info = (Map<String, String>)map.get("looker");
        String result = "info:" + info;
        return result;
    }
}

场景3:与@InitBinder注解组合使用,完成全局数据预处理(请求参数预处理)

SpringBoot - @InitBinder注解详解

使用总结

A. 在Controller中定义一个方法public void initBinder(WebDataBinder binder) {};
B. 在initBinder方法上添加注解:@InitBinder;
C. 一般会定义一个Controller的基类,在该基类中定义initBinder方法。

示例代码
/**
 * WEB层通用数据处理
 * @author ROCKY
 */
public class BaseController {

    /**
     * 将前台传递过来的日期格式的字符串转化为Date类型,否则无法将数据绑定到实体中。
     * 自定义类型转换器有两种方式:A. implements Converter<String, Date> 或者 B. extends PropertyEditorSupport;
     * 在WebDataBinder对象中,可以设置前缀,可以设置允许、禁止的字段、必填字段以及验证器,可以自定义类型转换器。
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // Date 类型转换
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(DateUtils.parseDate(text));
            }
        });
    }
}
SpringBoot中@ControllerAdvice/@RestControlAdvice+@ExceptionHandler实现全局异常捕获与处理 在编写Controller接口时,为避免接口因为未知的异常导致返回不友好的结果和提示。如果不进行全局异常捕获则需要对每个接口进行try-catch或其他操作。可以对Controller进行全局的异常捕获和处理,一旦发生异常,则返回通用的500响应码与通用错误提示。并将异常发生的具体的文件、类、方法、行数信息记录到日志。@ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器, 阅读详情

相关推荐

[Java实战]springboot注解@ControllerAdvice解析(十二)

注解在 Spring Boot 项目中有着广泛的应用场景。它不仅可以实现全局异常处理,减少代码冗余,提高代码的可维护性;还可以统一响应格式,方便前端进行处理;还能对控制器方法进行增强,实现通用的日志记录、权限验证等功能;并且可以实现跨多个控制器共享数据,避免重复获取数据。总之,是一个非常实用的注解,它能够帮助我们编写出更加优雅、简洁、可维护的代码。在实际开发中,我们应该充分了解并合理利用的这些功能,提升我们的开发效率和代码质量。

曼岛_的博客 862

@ControllerAdvice 的介绍及三种用法(转载)

然后,我们来看一下此类的注释:这个类是为那些声明了(@ExceptionHandler、@InitBinder 或 @ModelAttribute注解修饰的)方法的类而提供的专业化的@Component , 以供多个 Controller类所共享。说白了,就是aop思想的一种实现,你告诉我需要拦截规则,我帮你把他们拦下来,具体你想做更细致的拦截筛选和拦截之后的处理,你自己通过@ExceptionHandler、@InitBinder 或 @ModelAttribute这三个注解以及被其注解的方法来自定义。初

VIBE的博客 1万+

SpringMVC @ControllerAdvice使用场景

主要介绍了SpringMVC @ControllerAdvice使用场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

@ControllerAdvice 的介绍及三种用法

@ControllerAdvice 的介绍及三种用法 浅析@ControllerAdvice 首先,ControllerAdvice本质上是一个Component,因此也会被当成组建扫描,一视同仁,扫扫扫。 然后,我们来看一下此类的注释: 这个类是为那些声明了(@ExceptionHandler、@InitBinder 或 @ModelAttribute注解修饰的)方法的类而提供的专业化的...

fadai 10万+

北理计算机考研复试经验贴

很早就想写一篇复试经验贴,因为关于复试,消息相对初试少很多,尤其北理,关于具体怎么考,网上信息更是匮乏,之前自己也是死缠烂打,一路追着各位学姐学长问经验,求助老师才一路走过来,至今还没有看过系统完整的北理计算机的复试经验贴,后又经过老师提醒,借此机会开始好好总结一下,希望帮到你们。 首先希望学弟学妹不管初试成绩是高是低对复试都要足够的重视,因为复试1分相当于初试的5分,而且去年今年都有初试前几名...

wusiji8121的博客 2万+

电力现货市场出清机制解析:从理论到实践(附节点电价计算实例)

本文深入解析电力现货市场的核心出清机制,重点阐述了节点边际电价的计算原理与实践方法。通过对比系统边际电价、节点边际电价和分区边际电价三种模式,揭示了市场出清价格如何反映电力供需与网络阻塞。文章结合IEEE 30节点系统,提供了基于MATLAB和最优潮流模型的计算实例,详细展示了从构建模型到求解对偶变量以获取节点电价的全过程,为理解电力市场定价机制提供了从理论到实践的完整路径。

whisky的博客 757

Spring Boot中关于@ControllerAdvice注解的使用

一、处理全局异常 二、预设全局数据 三、请求参数预处理

huangjhai的博客 910

fluent linux运行算例,Fluent算例精选|03利用VOF和蒸发-冷凝模型

通过学习本算例您将获得?1、学会基本的VOF模型设置流程2、学会利用蒸发-冷凝模型来模拟传热沸腾目录1摘要42传热沸腾模型介绍43前处理44求解设置54.1启动Fluent54.2网格缩放64.3求解器设置74.4多相流模型设置84.5能量方程求解设置94.6紊流模型设置104.7添加材料114.8多相流中相设置124.9操作条件设置144.10边界条件设置154.10.1heatsource边界...

weixin_33278819的博客 3186

SpringBoot处理异常的相关注解 - @ControllerAdvice注解

本文详细叙述了@ControllerAdvice注解的基本概念、用途、基本使用、属性、@ControllerAdvice 与其他注解联合使用?异常处理方法 @ExceptionHandler、绑定数据方法 @InitBinder、模型数据方法 @ModelAttribute 、@RestControllerAdvice注解 与 @ControllerAdvice注解的区别?@ControllerAdvice和@ExceptionHandler结合使用、等问题

jiayoudangdang的博客 1484

代码实现 —— 基于 STM32 的可见光通信系统课程设计

基于STM32F103ZET6,源码如需移植,需要修改定时器捕获通道引脚,及定时器,如果你也有这个课设任务,希望对你有所帮助。

不善挽留 1万+

Type-C连接中的CC引脚:Rp与Rd电阻的识别与供电模式选择

本文深入解析Type-C接口中CC引脚的核心功能,包括Rp与Rd电阻的识别原理及供电模式选择机制。通过详细的分压计算和实战案例,揭示Type-C设备如何通过CC引脚实现方向检测、角色识别和供电协商,为硬件设计提供关键指导。

weixin_30616969的博客 343

SpringBoot 增强Controller方法,@ControllerAdvice注解的使用

⏹SpringBoot 增强Controller方法,@ControllerAdvice注解的使用

菜鸟记录 1万+

微信小程序 - 详细实现随机生成订单号,微信小程序创建订单号思路,不重复订单号生成的方法,小程序自动生成固定规则的订单号流水号(必须是唯一不重复的订单号,生成唯一订单号)详细生成方法,示例代码教程最新

微信小程序,vue2,vue3,订单号,流水号思路,微信小程序 详细实现随机生成订单号(JavaScript),随机生成商户订单号,根据当前时间随机生成流水号或者订单号,微信小程序之商家订单,订单号随机生成器,自动生成固定规则的订单号(前缀+采购日期+6位流水号)微信小程序 生成外卖顺序号,生成订单号或流水号简单方法,实现订单号生成唯一的解决方案,如何按日期生成订单号,14位编号=8位日期(+6位流水号),自动生成订单号(固定+日期+数字),销售订单号自动生成。在微信小程序开发中,详解实现随机生成创建订单号

🏆 前端领域优质创作者 1189

springboot中@ControllerAdvice和@RestControllerAdvice注解用法

springboot中@ControllerAdvice和@RestControllerAdvice注解用法1.@ControllerAdvice和@RestControllerAdvice的作用1.1 用于处理全局异常1.1.1 出现异常1.1.2 视图模板1.1.3 捕获异常并且跳转到视图1.2 全局数据绑定1.2.1 定义全局数据1.2.2 使用全局数据,哪个controller都可以调用1.3 全局数据预处理1.3.1 model1.3.1 预处理1.3.1 测试,发现如果没加预处理时的前缀,都会报

weixin_41359273的博客 1456

某Z节验证码

某Z节验证码、captchaBody、滑块、旋转、空间推理

mamenqi_csdn的博客 773

爬取Unsplash高清壁纸:Python爬虫实战教程(最新技术)

在当今数字化时代,高清壁纸已经成为人们个性化设备的重要元素。Unsplash作为全球最知名的免费高质量图片网站,汇集了数百万张由全球摄影师贡献的高清图片。然而,Unsplash官网的下载方式需要手动操作,对于需要批量下载壁纸的用户来说效率较低。本文将带你深入探索如何使用Python爬虫技术高效爬取Unsplash高清壁纸,从基础到进阶,全面掌握图片爬取的核心技术。Unsplash成立于2013年,是一个完全免费的图片分享平台。高质量内容:所有图片均由专业摄影师上传,分辨率普遍达到4K以上免费商用。

2201_76125261的博客 937

SpringBoot 如何使用 @ControllerAdvice 注解进行全局异常处理

ControllerAdvice 注解是 Spring Framework 3.2 引入的一个新特性,它用于定义全局异常处理器。使用 @ControllerAdvice 注解,我们可以集中处理所有 Controller 层抛出的异常,而不必在每个 Controller 中单独处理。

程序猿徐师兄的博客 1472

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

SpringBoot异常处理之注解@ExceptionHander和@ControllerAdvice

【代码】SpringBoot异常处理之注解@ExceptionHander和@ControllerAdvice。

只恨天高的博客 264

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

SpringBoot 中 @ControllerAdvice 注解

SpringBoot 中 @ControllerAdvice @ControllerAdvice 是 Spring 3.2 提供的新注解,应用在处理全局异常、全局数据绑定、全局数据预处理等方面。 我在一个 SpringBoot 项目中,处理全局异常,Controller 类中的异常统一由 ControllerExceptionHandler 类处理,至于它的底层源码只是大概阅读了一下,还没有很深刻的见解。我的代码如下: package com.fzshuai.handler; import org.slf

软件二班傅同学的博客 399

springboot(12):@ControllerAdvice和@RestControllerAdvice注解使用

@ControllerAdvice和@RestControllerAdvice注解使用

qq_43745578的博客 2278

springboot基于@ControllerAdvice注解的自定义异常

1.首先通过controller制造异常 @RestController @RequestMapping("item") public class ItemController { @Autowired private ItemService itemService; @PostMapping @ResponseBody public Respons...

陌子曦的专栏 1223

SpringBoot使用@ControllerAdvice注解

@ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理。主要作用有一下三种 通过@ControllerAdvice注解可以将对于控制器的全局配置放在同一个位置。 注解了@ControllerAdvice的类的方法可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上。 @ExceptionHandler:用于全局处

CharlesYooSky的博客 1462

SpringBoot @ControllerAdvice注解自定义全局异常处理类 统一处理异常

在Springboot或者Springcloud开发中为了统一处理业务异常,需要自定义全局异常处理类统一处理业务异常。在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping注解的方法中,本篇内容笔者讲解一下使用@ControllerA...

奋斗的IT青年 2973

Spring Boot | Cloud 的全局异常——@ControllerAdvice注解不起作用

失效解决方法:在@SpringBootApplication后面加上(scanBasePackages=”your package path to ‘@ControllerAdvice’ class”) E.G:

无糖 5738
上一篇: SpringBoot - @RequestBody、@ResponseBody的使用场景
下一篇: SpringBoot - SWAGGER中配置.pathMapping(“XXXX“)引发的404错误
cloneme01
博客等级 码龄20年 2万+粉丝 248原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

cloneme01

谢谢您的支持与鼓励!

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

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

打赏作者

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

抵扣说明:

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

余额充值