Эх сурвалжийг харах

fix:全局拦截异常,定义状态码602为解析数据源信息异常返前端重新登录 自定义租户异常类

韩帛霖 1 жил өмнө
parent
commit
fd6085f7a2

+ 0 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/DataSourceController.java

@@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 
-@Anonymous
 @RestController
 @RequestMapping("/dataSource")
 public class DataSourceController {

+ 1 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/TableInfoController.java

@@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.*;
 import javax.annotation.Resource;
 import java.util.Map;
 
-@Anonymous
 @RestController
 @RequestMapping("tableInfo")
 public class TableInfoController {
@@ -146,6 +145,7 @@ public class TableInfoController {
     /**
      * 初始化数据库,基础表
      */
+    @Anonymous
     @PostMapping("/initDatabase")
     public AjaxResult initDatabase(@RequestBody DataSource dataSource) {
         return tableInfoService.initDatabase(dataSource);

+ 6 - 3
ruoyi-common/src/main/java/com/ruoyi/common/constant/HttpStatus.java

@@ -2,11 +2,10 @@ package com.ruoyi.common.constant;
 
 /**
  * 返回状态码
- * 
+ *
  * @author ruoyi
  */
-public class HttpStatus
-{
+public class HttpStatus {
     /**
      * 操作成功
      */
@@ -91,4 +90,8 @@ public class HttpStatus
      * 系统警告消息
      */
     public static final int WARN = 601;
+    /**
+     * 系统警告消息:数据源信息未找到!认证失败。
+     */
+    public static final int ERRORWARN = 602;
 }

+ 29 - 0
ruoyi-common/src/main/java/com/ruoyi/common/exception/tenantdatassource/TenantDataSource.java

@@ -0,0 +1,29 @@
+package com.ruoyi.common.exception.tenantdatassource;
+
+/**
+ * @author hanzihang
+ * @date 2023/9/20 5:16
+ */
+public class TenantDataSource extends RuntimeException {
+
+    public TenantDataSource() {
+        super();
+    }
+
+    public TenantDataSource(String message) {
+        super(message);
+    }
+
+    public TenantDataSource(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public TenantDataSource(Throwable cause) {
+        super(cause);
+    }
+
+    public TenantDataSource(Object message, Object code) {
+        super(message.toString());
+    }
+
+}

+ 2 - 1
ruoyi-common/src/main/java/com/ruoyi/common/utils/SecurityUtils.java

@@ -1,5 +1,6 @@
 package com.ruoyi.common.utils;
 
+import com.ruoyi.common.exception.tenantdatassource.TenantDataSource;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -64,7 +65,7 @@ public class SecurityUtils {
         try {
             return getLoginUser().getUser().getTenant().getDataSource().getDatabaseType();
         } catch (Exception e) {
-            throw new ServiceException("获取获取数据源类型异常", HttpStatus.UNAUTHORIZED);
+            throw new TenantDataSource("未解析到当前请求中数据源信息", HttpStatus.ERRORWARN);
         }
     }
 

+ 7 - 1
ruoyi-framework/pom.xml

@@ -18,7 +18,7 @@
     <dependencies>
 
         <!-- SpringBoot Web容器 -->
-         <dependency>
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
@@ -59,6 +59,12 @@
             <artifactId>ruoyi-system</artifactId>
         </dependency>
 
+        <!-- 数据源模块-->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>zkqy-datamodeling</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 29 - 9
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/SqlInterceptor.java

@@ -1,10 +1,18 @@
 package com.ruoyi.framework.aspectj;
 
+import com.alibaba.fastjson2.JSON;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.exception.tenantdatassource.TenantDataSource;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.ServletUtils;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.reflect.ReflectUtils;
+import com.ruoyi.framework.web.service.TokenService;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.plugin.*;
+import org.aspectj.lang.annotation.Before;
 
+import java.lang.reflect.InvocationTargetException;
 import java.sql.Connection;
 import java.util.Properties;
 
@@ -24,11 +32,16 @@ public class SqlInterceptor implements Interceptor {
         String sql = statementHandler.getBoundSql().getSql();
         // 修改SQL语句
         String modifiedSql = BeforeSQL(sql);
-        // 将修改后的SQL语句设置回StatementHandler
-        ReflectUtils.setFieldValue(statementHandler.getBoundSql(), "sql", modifiedSql);
-        invocation.proceed();
-        ReflectUtils.setFieldValue(statementHandler.getBoundSql(), "sql", sql);
-        return invocation.proceed();
+        if (modifiedSql.equals("error")) {
+            // 终止程序
+            return AjaxResult.error("当前用户没有数据源信息!");
+        } else {
+            // 将修改后的SQL语句设置回StatementHandler
+            ReflectUtils.setFieldValue(statementHandler.getBoundSql(), "sql", modifiedSql);
+            invocation.proceed();
+            ReflectUtils.setFieldValue(statementHandler.getBoundSql(), "sql", sql);
+            return invocation.proceed();
+        }
     }
 
     // 根据类型设置不同的选择数据源格式
@@ -36,7 +49,7 @@ public class SqlInterceptor implements Interceptor {
         try {
             SecurityUtils.getDatabaseType();
         } catch (Exception e) {
-            return sql;
+            return "error";
         }
         if (SecurityUtils.getDatabaseType().equals("sqlserver"))
             return "USE `" + SecurityUtils.getDatabaseName() + "`; " + sql;
@@ -44,7 +57,7 @@ public class SqlInterceptor implements Interceptor {
             return "set schema " + SecurityUtils.getDatabaseName() + "; " + sql;
         if (SecurityUtils.getDatabaseType().equals("mysql"))
             return "USE `" + SecurityUtils.getDatabaseName() + "`; " + sql;
-        return sql;
+        return "error";
     }
 
     // 根据类型设置不同的选择数据源格式
@@ -52,7 +65,14 @@ public class SqlInterceptor implements Interceptor {
         try {
             SecurityUtils.getDatabaseType();
         } catch (Exception e) {
-            return sql;
+            /**
+             * 如何当前请求中并不携带该用户的数据源信息
+             * 分两种情况:
+             * 1.当前用户并没有数据源信息(例如:admin并没有从库数据源信息)
+             * 2.当前用户的token失效(理论上在客户端发送请求时会携带token,逻辑代码执行前会首先验证token的有效性)
+             * 几乎不会出现第二种情况
+             */
+            return "error";
         }
         if (SecurityUtils.getDatabaseType().equals("sqlserver"))
             return "USE `" + SecurityUtils.getDatabaseName() + "`; ";
@@ -60,7 +80,7 @@ public class SqlInterceptor implements Interceptor {
             return "set schema " + SecurityUtils.getDatabaseName() + "; ";
         if (SecurityUtils.getDatabaseType().equals("mysql"))
             return "USE `" + SecurityUtils.getDatabaseName() + "`; ";
-        return sql;
+        return "error";
     }
 
 

+ 31 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionAspect.java

@@ -0,0 +1,31 @@
+package com.ruoyi.framework.web.exception;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+/**
+ * 拦截实现类中的异常信息
+ *
+ * @author hzh
+ * @date 2023-09-21
+ */
+@Aspect
+@Component
+public class GlobalExceptionAspect {
+    // com.ruoyi.system.service.impl
+    // datamodeling
+    @Around("execution(* com.zkqy.datamodeling..*(..))") // 切入点表达式
+    public Object handleExceptionALL(ProceedingJoinPoint joinPoint) throws Throwable {
+        try {
+            return joinPoint.proceed(); // 继续执行被拦截的方法  
+        } catch (Exception e) {
+            // 处理异常
+            System.err.println(e);
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+}

+ 28 - 19
ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java

@@ -1,6 +1,8 @@
 package com.ruoyi.framework.web.exception;
 
 import javax.servlet.http.HttpServletRequest;
+
+import com.ruoyi.common.exception.tenantdatassource.TenantDataSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.access.AccessDeniedException;
@@ -17,20 +19,18 @@ import com.ruoyi.common.utils.StringUtils;
 
 /**
  * 全局异常处理器
- * 
+ *
  * @author ruoyi
  */
 @RestControllerAdvice
-public class GlobalExceptionHandler
-{
+public class GlobalExceptionHandler {
     private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
 
     /**
      * 权限校验异常
      */
     @ExceptionHandler(AccessDeniedException.class)
-    public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request)
-    {
+    public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
         String requestURI = request.getRequestURI();
         log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
         return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
@@ -41,8 +41,7 @@ public class GlobalExceptionHandler
      */
     @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
     public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
-            HttpServletRequest request)
-    {
+                                                          HttpServletRequest request) {
         String requestURI = request.getRequestURI();
         log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
         return AjaxResult.error(e.getMessage());
@@ -52,8 +51,7 @@ public class GlobalExceptionHandler
      * 业务异常
      */
     @ExceptionHandler(ServiceException.class)
-    public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
-    {
+    public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) {
         log.error(e.getMessage(), e);
         Integer code = e.getCode();
         return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
@@ -63,8 +61,7 @@ public class GlobalExceptionHandler
      * 拦截未知的运行时异常
      */
     @ExceptionHandler(RuntimeException.class)
-    public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
-    {
+    public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
         String requestURI = request.getRequestURI();
         log.error("请求地址'{}',发生未知异常.", requestURI, e);
         return AjaxResult.error(e.getMessage());
@@ -74,8 +71,7 @@ public class GlobalExceptionHandler
      * 系统异常
      */
     @ExceptionHandler(Exception.class)
-    public AjaxResult handleException(Exception e, HttpServletRequest request)
-    {
+    public AjaxResult handleException(Exception e, HttpServletRequest request) {
         String requestURI = request.getRequestURI();
         log.error("请求地址'{}',发生系统异常.", requestURI, e);
         return AjaxResult.error(e.getMessage());
@@ -85,8 +81,7 @@ public class GlobalExceptionHandler
      * 自定义验证异常
      */
     @ExceptionHandler(BindException.class)
-    public AjaxResult handleBindException(BindException e)
-    {
+    public AjaxResult handleBindException(BindException e) {
         log.error(e.getMessage(), e);
         String message = e.getAllErrors().get(0).getDefaultMessage();
         return AjaxResult.error(message);
@@ -96,8 +91,7 @@ public class GlobalExceptionHandler
      * 自定义验证异常
      */
     @ExceptionHandler(MethodArgumentNotValidException.class)
-    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
-    {
+    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
         log.error(e.getMessage(), e);
         String message = e.getBindingResult().getFieldError().getDefaultMessage();
         return AjaxResult.error(message);
@@ -107,8 +101,23 @@ public class GlobalExceptionHandler
      * 演示模式异常
      */
     @ExceptionHandler(DemoModeException.class)
-    public AjaxResult handleDemoModeException(DemoModeException e)
-    {
+    public AjaxResult handleDemoModeException(DemoModeException e) {
         return AjaxResult.error("演示模式,不允许操作");
     }
+
+    /**
+     * 租户用户请求接口携带信息异常
+     */
+    @ExceptionHandler(ClassCastException.class)
+    public AjaxResult handleTenantDateSource(ClassCastException t) {
+        return AjaxResult.error(602, "解析租户数据源异常");
+    }
+
+    /**
+     * 租户用户请求接口携带信息异常
+     */
+    @ExceptionHandler(TenantDataSource.class)
+    public AjaxResult handleTenantDateSource(TenantDataSource t) {
+        return AjaxResult.error(602, "解析租户数据源异常");
+    }
 }

+ 1 - 1
zkqy-datamodeling/src/main/java/com/zkqy/datamodeling/service/impl/TableInfoServiceImpl.java

@@ -153,7 +153,7 @@ public class TableInfoServiceImpl implements ITableInfoService {
         String username = (String) map.get("username");
 
         if (!StringUtils.hasLength(databaseType)) {
-            return AjaxResult.error("当前用户没有数据源,无法查看该页面");
+            return AjaxResult.error(602, "无法解析数据源信息!");
         }
 
         //获取数据源信息