https://www.jb51.net/article/162919.htm
前言
在後端發生異常或者是請求出錯時,前端通常顯示如下
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Jun 07 15:38:07 CST 2019
There was an unexpected error (type=Not Found, status=404).
No message available
對於用戶來說非常不友好。
本文主要講解如何在SpringBoot應用中使用統一異常處理。
實現方式
- 第一種:使用@ControllerAdvice和@ExceptionHandler註解
- 第二種: 使用ErrorController類來實現。
第一種:使用@ControllerAdvice和@ExceptionHandler註解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler (NullPointerException. class )
public BaseResult globalException(HttpServletResponse response,NullPointerException ex){
log.info( "GlobalExceptionHandler..." );
log.info( "錯誤代碼:" + response.getStatus());
BaseResult result = new WebResult(WebResult.RESULT_FAIL, "request error:" +response.getStatus()
, "GlobalExceptionHandler:" +ex.getMessage());
return result;
}
}
|
註解@ControllerAdvice表示這是一個控制器增強類,當控制器發生異常且符合類中定義的攔截異常類,將會被攔截。
可以定義攔截的控制器所在的包路徑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Target ({ElementType.TYPE})
@Retention (RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
@AliasFor ( "basePackages" )
String[] value() default {};
@AliasFor ( "value" )
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] assignableTypes() default {};
Class<? extends Annotation>[] annotations() default {};
}
|
註解ExceptionHandler定義攔截的異常類
1
2
3
4
5
6
|
@Target ({ElementType.METHOD})
@Retention (RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
Class<? extends Throwable>[] value() default {};
}
|
第二種: 使用ErrorController類來實現。
系統默認的錯誤處理類爲BasicErrorController,將會顯示如上的錯誤頁面。
這裏編寫一個自己的錯誤處理類,上面默認的處理類將不會起作用。
getErrorPath()返回的路徑服務器將會重定向到該路徑對應的處理類,本例中爲error方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@Slf4j
@RestController
public class HttpErrorController implements ErrorController {
private final static String ERROR_PATH = "/error" ;
@ResponseBody
@RequestMapping (path = ERROR_PATH )
public BaseResult error(HttpServletRequest request, HttpServletResponse response){
log.info( "訪問/error" + " 錯誤代碼:" + response.getStatus());
BaseResult result = new WebResult(WebResult.RESULT_FAIL, "HttpErrorController error:" +response.getStatus());
return result;
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}
|
測試
以上定義了一個統一的返回類BaseResult,方便前端進行處理。
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
|
package com.microblog.common.result;
import java.io.Serializable;
public class BaseResult implements Serializable {
private static final long serialVersionUID = 1L;
public static final int RESULT_FAIL = 0 ;
public static final int RESULT_SUCCESS = 1 ;
//返回代碼
private Integer code;
//返回消息
private String message;
//返回對象
private Object data;
public BaseResult(Integer code, String message) {
this .code = code;
this .message = message;
}
public BaseResult(Integer code, String message, Object object) {
this .code = code;
this .message = message;
this .data = object;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this .code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this .message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this .data = data;
}
}
|
編寫一個測試控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Slf4j
@RestController
@RequestMapping ( "/user" )
public class TestController {
@RequestMapping ( "/info1" )
public String test(){
log.info( "/user/info1" );
throw new NullPointerException( "TestController have exception" );
}
}
|
1.發出一個錯誤的請求,也就是沒有對應的處理類。
從返回可以看到是由HttpErrorController類處理
1
|
{ "code" : 0 , "message" : "HttpErrorController error:404" , "data" : null }
|
2.發出一個正常的請求(TestController的test()處理),處理類中拋出空異樣
從返回中可以看出是由GlobalExceptionHandler類處理
1
|
{ "code" : 0 , "message" : "request error:200" , "data" : "GlobalExceptionHandler:TestController have exception" }
|
區別
1.註解@ControllerAdvice方式只能處理控制器拋出的異常。此時請求已經進入控制器中。
2.類ErrorController方式可以處理所有的異常,包括未進入控制器的錯誤,比如404,401等錯誤
3.如果應用中兩者共同存在,則@ControllerAdvice方式處理控制器拋出的異常,類ErrorController方式未進入控制器的異常。
4.@ControllerAdvice方式可以定義多個攔截方法,攔截不同的異常類,並且可以獲取拋出的異常信息,自由度更大。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。