基于@RestControllerAdvice与@ControllerAdvice的区别说明
作者:y_bccl27 发布时间:2022-06-24 21:00:36
@RestControllerAdvice与@ControllerAdvice的区别
@RestControllerAdvice注解与@ControllerAdvice注解位于同一个依赖包下面,其pom依赖为:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.3</version>
</dependency>
有时会发现在不同的项目中,全局异常处理部分,有的自定义类添加@RestControllerAdvice注解,有的自定义类添加@ControllerAdvice注解。
其实这两个注解的作用基本上是一致的,都是为了实现自定义全局异常处理,
唯一的区别是:@RestControllerAdvice注解包含了@ControllerAdvice注解和@ResponseBody注解。
@ControllerAdvice注解的源码为
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
}
@RestControllerAdvice注解的源码为
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
}
当自定义类加@ControllerAdvice注解时,方法需要返回json数据时,每个方法还需要添加@ResponseBody注解
当自定义类加@RestControllerAdvice注解时,方法自动返回json数据,每个方法无需再添加@ResponseBody注解
/**
* 全局异常处理类
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Result<String> ExceptionHandler(Exception e) {
log.error("出现异常:", e);
return Result.failed(e.getMessage());
}
}
@RestControllerAdvice @ControllerAdvice注解无效 通用异常处理
简单记录下,今天打算写一个公共异常处理切面,主要是将所有抛出的异常拦截,然后返回给前端的时候,统一是错误码,错误原因等。防止直接在前端抛出错误。
@RestControllerAdvice 或者 @ControllerAdvice 可以直接作为错误处理的切面对待。但是使用过程中发现这两个注解无效,原因是我将GlobalExceptionHandler定义在另一个包里面,@SpringBootApplication无法自动加载到该注解(springboot启动类的默认扫描路径是该类所在的包下面的所有java类。
如:启动类在“com.galen.cloud.portal”包下,那么只有com.galen.cloud.portal包下的类会被扫描加载)。所以添加上对应的scanBasePackages 即可(我这边改为扫描所有匹配com.galen.*的包):
启动类
package com.galen.cloud.portal;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.galen.*")
public class galenPortalApplication {
public static void main(String[] args) {
SpringApplication.run(galenPortalApplication.class, args);
}
}
错误处理类
package com.galen.common.exception;
import com.galen.common.core.domain.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 异常处理器
* @author galen
*/
@RestControllerAdvice
public class GlobalExceptionHandler
{
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 请求方式不支持
*/
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
@ResponseStatus(code = HttpStatus.METHOD_NOT_ALLOWED)
public R handleException(HttpRequestMethodNotSupportedException e)
{
logger.error(e.getMessage(), e);
return R.error("不支持' " + e.getMethod() + "'请求");
}
/**
* 拦截未知的运行时异常
*/
@ExceptionHandler(RuntimeException.class)
public R notFount(RuntimeException e)
{
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
{
throw e;
}
logger.error("运行时异常:", e);
return R.error("运行时异常:" + e.getMessage());
}
/**
* 处理自定义异常
*/
@ExceptionHandler(galenException.class)
public R handleWindException(galenException e)
{
return R.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(DuplicateKeyException.class)
public R handleDuplicateKeyException(DuplicateKeyException e)
{
logger.error(e.getMessage(), e);
return R.error("数据库中已存在该记录");
}
@ExceptionHandler(Exception.class)
public R handleException(Exception e) throws Exception
{
logger.error(e.getMessage(), e);
return R.error("服务器错误,请联系管理员");
}
/**
* 捕获并处理未授权异常
*
* @param e 授权异常
* @return 统一封装的结果类, 含有代码code和提示信息msg
*/
@ExceptionHandler(UnauthorizedException.class)
public R handle401(UnauthorizedException e)
{
return R.error(401, e.getMessage());
}
// 验证码错误
@ExceptionHandler(ValidateCodeException.class)
public R handleCaptcha(ValidateCodeException e)
{
return R.error(e.getMessage());
}
}
最后拦截效果图如下:
来源:https://blog.csdn.net/y_bccl27/article/details/120219882


猜你喜欢
- 本文实例为大家分享了C#实现chart控件动态曲线绘制的具体代码,供大家参考,具体内容如下思想实验室要做一个动态曲线绘制,网上方法很多,但是
- 一、什么是轻量级锁轻量级锁是JDK 6之中加入的新型锁机制,它名字中的“轻量级”是相对于使用moni
- 要爬取一个网站遇到了极验的验证码,这周都在想着怎么破解这个,网上搜了好多知乎上看到有人问了这问题,我按照这思路去大概实现了一下。1.使用ht
- C语言是一种高级编程语言,其最重要的特点之一是它允许程序员使用函数来组织代码。函数是一组相关的指令的集合,可以在程序中多次调用。在 C语言中
- 前言集合就是一组数的集合,就像是一个容器,但是我们应该清楚的是集合中存放的都是对象的引用,而不是真正的实体。而我们常说的集合中的对象其实指的
- 1.数据数据(Data)是外部世界信息的载体, 是能够被计算机识别,加工,存储的。在现实生活中也就是我们的产品原材料。计算机中的数据包括数值
- 图库在播放幻灯片时,按power键灭屏,然后再亮屏,会发现幻灯片继续在播放,没有显示keyguard。如何在亮屏后显示解锁界面。 修改方法是
- JAVA 中Spring的@Async用法总结引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方
- 前言 同源策略:判断是否是同源的,主要看这三点,协议,ip,端口。同源策略就是浏览器出于网站安全性的考虑,限制不同源之间的资源相互访问的一种
- 一、Container 简介flutter 开发中最核心的是用最少的组件(层次)完成功能开发;Container 前端的盒子模型实现,类似
- 使用springboot创建多module项目,以前也做过多次,一段时间不用又忘了,在这里做个记录项目名称作用说明demo-root根项目父
- 本文实例讲述了Android编程中File文件常见存储与读取操作。分享给大家供大家参考,具体如下:MainActivity文件代码如下:pa
- java中的JsonSerializer用法背景今天在写项目的时候遇到一个问题,项目中有个类中有创建时间和更新时间两个属性,但是单位在后端用
- 站点IP访问频率限制 针对单个站点using System;using System.Collections.Generic;u
- MyCat一个彻底开源的,面向企业应用开发的大数据库集群。基于阿里开源的Cobar产品而研发。能满足数据库数据大量存储;提高了查询性能。文章
- 一、前言写今天这篇文章的缘由,其实是来自于前段时间和粉丝的一个聊天,最近他打算参加游戏创作大赛,问我需要准备学习什么知识,以及参加比赛的注意
- 1. 描述线程与进程的区别? 什么是Windows服务,它的生命周期与标准的EXE程序有什么不同 Windows上的单个进程所能访问的最大内
- 上一次接触到编码的知识,还是上大学的时候,那时候学的是通信工程专业,有关编码的内容,不记得是在通信原理还是信息论与编码里面学到的了。却依然记
- 《IDEA 破解新招 - 无限重置30天试用期》,这种方法适用idea2021以下所有版本,亲测idea2020.3成功激活,其他版本自测吧
- 缘起经过前面三章的入门,我们大概了解了Mybatis的主线逻辑是什么样子的,在本章中,我们将正式进入Mybatis的源码海洋。Mybatis