基于@RestControllerAdvice与@ControllerAdvice的区别说明
目录
- @RestControllerAdvice与@ControllerAdvice的区别
- @ControllerAdvice注解的源码为
- @RestControllerAdvice注解的源码为
- @RestControllerAdvice @ControllerAdvice注解无效 通用异常处理
- 启动类
- 错误处理类
@RestControllerAdvice与@ControllerAdvice的区别 @RestControllerAdvice注解与@ControllerAdvice注解位于同一个依赖包下面,其pom依赖为:
org.springframework spring-web5.3.3
有时会发现在不同的项目中,全局异常处理部分,有的自定义类添加@RestControllerAdvice注解,有的自定义类添加@ControllerAdvice注解。
其实这两个注解的作用基本上是一致的,都是为了实现自定义全局异常处理,
唯一的区别是:@RestControllerAdvice注解包含了@ControllerAdvice注解和@ResponseBody注解。
@ControllerAdvice注解的源码为
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface ControllerAdvice { }
@RestControllerAdvice注解的源码为
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@ControllerAdvice@ResponseBodypublic @interface RestControllerAdvice { }
当自定义类加@ControllerAdvice注解时,方法需要返回json数据时,每个方法还需要添加@ResponseBody注解
当自定义类加@RestControllerAdvice注解时,方法自动返回json数据,每个方法无需再添加@ResponseBody注解
/** * 全局异常处理类 */@RestControllerAdvice@Slf4jpublic class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public Result 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 */@RestControllerAdvicepublic 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()); }}
最后拦截效果图如下:
文章图片
【基于@RestControllerAdvice与@ControllerAdvice的区别说明】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 第326天
- Shell-Bash变量与运算符
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 逻辑回归的理解与python示例
- Guava|Guava RateLimiter与限流算法
- 我和你之前距离