Przeglądaj źródła

全局异常处理(网关异常&业务异常)

RuoYi 5 lat temu
rodzic
commit
1b70ef990b

+ 2 - 1
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java

@@ -31,10 +31,11 @@ public class Constants
31 31
      * 成功标记
32 32
      */
33 33
     public static final Integer SUCCESS = 200;
34
+
34 35
     /**
35 36
      * 失败标记
36 37
      */
37
-    public static final Integer FAIL = 501;
38
+    public static final Integer FAIL = 500;
38 39
 
39 40
     /**
40 41
      * 登录成功

+ 18 - 12
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/R.java

@@ -12,6 +12,12 @@ public class R<T> implements Serializable
12 12
 {
13 13
     private static final long serialVersionUID = 1L;
14 14
 
15
+    /** 成功 */
16
+    public static final int SUCCESS = Constants.SUCCESS;
17
+
18
+    /** 失败 */
19
+    public static final int FAIL = Constants.FAIL;
20
+
15 21
     private int code;
16 22
 
17 23
     private String msg;
@@ -20,40 +26,40 @@ public class R<T> implements Serializable
20 26
 
21 27
     public static <T> R<T> ok()
22 28
     {
23
-        return restResult(null, Constants.SUCCESS, null);
29
+        return restResult(null, SUCCESS, null);
24 30
     }
25 31
 
26 32
     public static <T> R<T> ok(T data)
27 33
     {
28
-        return restResult(data, Constants.SUCCESS, null);
34
+        return restResult(data, SUCCESS, null);
29 35
     }
30 36
 
31 37
     public static <T> R<T> ok(T data, String msg)
32 38
     {
33
-        return restResult(data, Constants.SUCCESS, msg);
39
+        return restResult(data, SUCCESS, msg);
34 40
     }
35 41
 
36
-    public static <T> R<T> failed()
42
+    public static <T> R<T> fail()
37 43
     {
38
-        return restResult(null, Constants.FAIL, null);
44
+        return restResult(null, FAIL, null);
39 45
     }
40 46
 
41
-    public static <T> R<T> failed(String msg)
47
+    public static <T> R<T> fail(String msg)
42 48
     {
43
-        return restResult(null, Constants.FAIL, msg);
49
+        return restResult(null, FAIL, msg);
44 50
     }
45 51
 
46
-    public static <T> R<T> failed(T data)
52
+    public static <T> R<T> fail(T data)
47 53
     {
48
-        return restResult(data, Constants.FAIL, null);
54
+        return restResult(data, FAIL, null);
49 55
     }
50 56
 
51
-    public static <T> R<T> failed(T data, String msg)
57
+    public static <T> R<T> fail(T data, String msg)
52 58
     {
53
-        return restResult(data, Constants.FAIL, msg);
59
+        return restResult(data, FAIL, msg);
54 60
     }
55 61
 
56
-    public static <T> R<T> failed(int code, String msg)
62
+    public static <T> R<T> fail(int code, String msg)
57 63
     {
58 64
         return restResult(null, code, msg);
59 65
     }

+ 1 - 1
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/CustomAccessDeniedHandler.java

@@ -28,6 +28,6 @@ public class CustomAccessDeniedHandler extends OAuth2AccessDeniedHandler
28 28
         logger.info("权限不足,请联系管理员 {}", request.getRequestURI());
29 29
 
30 30
         String msg = authException.getMessage();
31
-        ServletUtils.renderString(response, JSON.toJSONString(R.failed(HttpStatus.FORBIDDEN, msg)));
31
+        ServletUtils.renderString(response, JSON.toJSONString(R.fail(HttpStatus.FORBIDDEN, msg)));
32 32
     }
33 33
 }

+ 117 - 0
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java

@@ -0,0 +1,117 @@
1
+package com.ruoyi.common.security.handler;
2
+
3
+import org.slf4j.Logger;
4
+import org.slf4j.LoggerFactory;
5
+import org.springframework.security.access.AccessDeniedException;
6
+import org.springframework.security.authentication.AccountExpiredException;
7
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
8
+import org.springframework.validation.BindException;
9
+import org.springframework.web.bind.MethodArgumentNotValidException;
10
+import org.springframework.web.bind.annotation.ExceptionHandler;
11
+import org.springframework.web.bind.annotation.RestControllerAdvice;
12
+import org.springframework.web.servlet.NoHandlerFoundException;
13
+import com.ruoyi.common.core.constant.HttpStatus;
14
+import com.ruoyi.common.core.exception.BaseException;
15
+import com.ruoyi.common.core.exception.CustomException;
16
+import com.ruoyi.common.core.exception.DemoModeException;
17
+import com.ruoyi.common.core.utils.StringUtils;
18
+import com.ruoyi.common.core.web.domain.AjaxResult;
19
+
20
+/**
21
+ * 全局异常处理器
22
+ * 
23
+ * @author ruoyi
24
+ */
25
+@RestControllerAdvice
26
+public class GlobalExceptionHandler
27
+{
28
+    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
29
+
30
+    /**
31
+     * 基础异常
32
+     */
33
+    @ExceptionHandler(BaseException.class)
34
+    public AjaxResult baseException(BaseException e)
35
+    {
36
+        return AjaxResult.error(e.getMessage());
37
+    }
38
+
39
+    /**
40
+     * 业务异常
41
+     */
42
+    @ExceptionHandler(CustomException.class)
43
+    public AjaxResult businessException(CustomException e)
44
+    {
45
+        if (StringUtils.isNull(e.getCode()))
46
+        {
47
+            return AjaxResult.error(e.getMessage());
48
+        }
49
+        return AjaxResult.error(e.getCode(), e.getMessage());
50
+    }
51
+
52
+    @ExceptionHandler(NoHandlerFoundException.class)
53
+    public AjaxResult handlerNoFoundException(Exception e)
54
+    {
55
+        log.error(e.getMessage(), e);
56
+        return AjaxResult.error(HttpStatus.NOT_FOUND, "路径不存在,请检查路径是否正确");
57
+    }
58
+
59
+    @ExceptionHandler(AccessDeniedException.class)
60
+    public AjaxResult handleAuthorizationException(AccessDeniedException e)
61
+    {
62
+        log.error(e.getMessage());
63
+        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
64
+    }
65
+
66
+    @ExceptionHandler(AccountExpiredException.class)
67
+    public AjaxResult handleAccountExpiredException(AccountExpiredException e)
68
+    {
69
+        log.error(e.getMessage(), e);
70
+        return AjaxResult.error(e.getMessage());
71
+    }
72
+
73
+    @ExceptionHandler(UsernameNotFoundException.class)
74
+    public AjaxResult handleUsernameNotFoundException(UsernameNotFoundException e)
75
+    {
76
+        log.error(e.getMessage(), e);
77
+        return AjaxResult.error(e.getMessage());
78
+    }
79
+
80
+    @ExceptionHandler(Exception.class)
81
+    public AjaxResult handleException(Exception e)
82
+    {
83
+        log.error(e.getMessage(), e);
84
+        return AjaxResult.error(e.getMessage());
85
+    }
86
+
87
+    /**
88
+     * 自定义验证异常
89
+     */
90
+    @ExceptionHandler(BindException.class)
91
+    public AjaxResult validatedBindException(BindException e)
92
+    {
93
+        log.error(e.getMessage(), e);
94
+        String message = e.getAllErrors().get(0).getDefaultMessage();
95
+        return AjaxResult.error(message);
96
+    }
97
+
98
+    /**
99
+     * 自定义验证异常
100
+     */
101
+    @ExceptionHandler(MethodArgumentNotValidException.class)
102
+    public Object validExceptionHandler(MethodArgumentNotValidException e)
103
+    {
104
+        log.error(e.getMessage(), e);
105
+        String message = e.getBindingResult().getFieldError().getDefaultMessage();
106
+        return AjaxResult.error(message);
107
+    }
108
+
109
+    /**
110
+     * 演示模式异常
111
+     */
112
+    @ExceptionHandler(DemoModeException.class)
113
+    public AjaxResult demoModeException(DemoModeException e)
114
+    {
115
+        return AjaxResult.error("演示模式,不允许操作");
116
+    }
117
+}

+ 2 - 1
ruoyi-common/ruoyi-common-security/src/main/resources/META-INF/spring.factories

@@ -1,5 +1,6 @@
1 1
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 2
   com.ruoyi.common.security.service.UserDetailsServiceImpl,\
3
-  com.ruoyi.common.security.handler.CustomAccessDeniedHandler
3
+  com.ruoyi.common.security.handler.CustomAccessDeniedHandler,\
4
+  com.ruoyi.common.security.handler.GlobalExceptionHandler
4 5
 
5 6
   

+ 66 - 0
ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java

@@ -0,0 +1,66 @@
1
+package com.ruoyi.gateway.handler;
2
+
3
+import org.springframework.cloud.gateway.support.NotFoundException;
4
+import org.slf4j.Logger;
5
+import org.slf4j.LoggerFactory;
6
+import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
7
+import org.springframework.context.annotation.Configuration;
8
+import org.springframework.core.annotation.Order;
9
+import org.springframework.core.io.buffer.DataBufferFactory;
10
+import org.springframework.http.HttpStatus;
11
+import org.springframework.http.MediaType;
12
+import org.springframework.http.server.reactive.ServerHttpResponse;
13
+import org.springframework.web.server.ResponseStatusException;
14
+import org.springframework.web.server.ServerWebExchange;
15
+import com.alibaba.fastjson.JSON;
16
+import com.ruoyi.common.core.domain.R;
17
+import reactor.core.publisher.Mono;
18
+
19
+/**
20
+ * 网关统一异常处理
21
+ *
22
+ * @author ruoyi
23
+ */
24
+@Order(-1)
25
+@Configuration
26
+public class GatewayExceptionHandler implements ErrorWebExceptionHandler
27
+{
28
+    private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class);
29
+
30
+    @Override
31
+    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
32
+    {
33
+        ServerHttpResponse response = exchange.getResponse();
34
+
35
+        if (exchange.getResponse().isCommitted())
36
+        {
37
+            return Mono.error(ex);
38
+        }
39
+
40
+        String msg;
41
+
42
+        if (ex instanceof NotFoundException)
43
+        {
44
+            msg = "服务未找到";
45
+        }
46
+        else if (ex instanceof ResponseStatusException)
47
+        {
48
+            ResponseStatusException responseStatusException = (ResponseStatusException) ex;
49
+            msg = responseStatusException.getMessage();
50
+        }
51
+        else
52
+        {
53
+            msg = "内部服务器错误";
54
+        }
55
+
56
+        log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage());
57
+
58
+        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
59
+        response.setStatusCode(HttpStatus.OK);
60
+
61
+        return response.writeWith(Mono.fromSupplier(() -> {
62
+            DataBufferFactory bufferFactory = response.bufferFactory();
63
+            return bufferFactory.wrap(JSON.toJSONBytes(R.fail(msg)));
64
+        }));
65
+    }
66
+}

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java

@@ -104,7 +104,7 @@ public class SysUserController extends BaseController
104 104
         SysUser sysUser = userService.selectUserByUserName(username);
105 105
         if (StringUtils.isNull(sysUser))
106 106
         {
107
-            return R.failed("用户名或密码错误");
107
+            return R.fail("用户名或密码错误");
108 108
         }
109 109
         // 角色集合
110 110
         Set<String> roles = permissionService.getRolePermission(sysUser.getUserId());