基于@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());
   }
}

最后拦截效果图如下:

基于@RestControllerAdvice与@ControllerAdvice的区别说明

来源:https://blog.csdn.net/y_bccl27/article/details/120219882

标签:@RestControllerAdvice,@ControllerAdvice
0
投稿

猜你喜欢

  • javaweb中Filter(过滤器)的常见应用

    2023-07-10 23:57:36
  • Spring之WEB模块配置详解

    2023-12-05 13:21:48
  • springboot2.x整合tkmapper的示例代码

    2021-09-19 11:56:59
  • C++语言io流处理基本操作教程示例

    2023-11-02 22:07:39
  • C#枚举类型与位域枚举Enum

    2023-03-02 06:52:27
  • 解析Mybatis SqlSessionFactory初始化原理

    2022-07-09 04:24:05
  • Java实战之实现用户登录

    2022-08-03 14:42:55
  • java使用Cookie判断用户登录情况的方法

    2021-11-28 15:12:40
  • Spring Boot用户注册验证的实现全过程记录

    2023-01-03 01:58:34
  • java.math包下计算浮点数和整数的类的实例

    2023-02-06 16:19:39
  • Unity实现10天签到系统

    2022-07-11 23:40:01
  • 详解Java使用Jsch与sftp服务器实现ssh免密登录

    2023-11-24 18:34:18
  • C++实现俄罗斯方块源码

    2023-06-27 23:49:14
  • Java web实现账号单一登录,防止同一账号重复登录(踢人效果)

    2021-05-24 13:26:09
  • c#中LINQ的基本用法(二)

    2022-05-29 07:00:43
  • Java获取接口所有实现类的方式详解

    2022-06-11 14:44:27
  • hibernate 中 fetch=FetchType.LAZY 懒加载失败处理方法

    2023-11-08 09:40:31
  • Java JDK动态代理实现原理实例解析

    2022-04-23 05:19:10
  • 详解java操作Redis数据库的redis工具(RedisUtil,jedis工具JedisUtil,JedisPoolUtil)

    2023-07-29 11:31:36
  • 浅谈Unity中的Shader

    2022-03-25 05:15:07
  • asp之家 软件编程 m.aspxhome.com