好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

@RestControllerAdvice与@ControllerAdvice的区别

@RestControllerAdvice注解与@ControllerAdvice注解位于同一个依赖包下面,其pom依赖为:

?

1

2

3

4

5

< dependency >

     < groupId >org.springframework</ groupId >

     < artifactId >spring-web</ artifactId >

     < version >5.3.3</ version >

</ dependency >

有时会发现在不同的项目中,全局异常处理部分,有的自定义类添加@RestControllerAdvice注解,有的自定义类添加@ControllerAdvice注解。

其实这两个注解的作用基本上是一致的,都是为了实现自定义全局异常处理,

唯一的区别是:@RestControllerAdvice注解包含了@ControllerAdvice注解和@ResponseBody注解。

@ControllerAdvice注解的源码为

?

1

2

3

4

5

6

@Target ({ElementType.TYPE})

@Retention (RetentionPolicy.RUNTIME)

@Documented

@Component

public @interface ControllerAdvice {

}

@RestControllerAdvice注解的源码为

?

1

2

3

4

5

6

7

@Target ({ElementType.TYPE})

@Retention (RetentionPolicy.RUNTIME)

@Documented

@ControllerAdvice

@ResponseBody

public @interface RestControllerAdvice {

}

当自定义类加@ControllerAdvice注解时,方法需要返回json数据时,每个方法还需要添加@ResponseBody注解

当自定义类加@RestControllerAdvice注解时,方法自动返回json数据,每个方法无需再添加@ResponseBody注解

?

1

2

3

4

5

6

7

8

9

10

11

12

13

/**

  * 全局异常处理类

  */

@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.*的包):

启动类

?

1

2

3

4

5

6

7

8

9

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);

     }

}

错误处理类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

package com.galen测试数据mon.exception;

import com.galen测试数据mon.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

查看更多关于基于@RestControllerAdvice与@ControllerAdvice的区别说明的详细内容...

  阅读:20次