@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.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