Quellcode durchsuchen

Fix 修复/resource/sse的satoken报错问题

Yue vor 1 Woche
Ursprung
Commit
d3487138b6

+ 10 - 5
SERVER/VberAdminPlusV3/vber-common/vber-common-security/src/main/java/com/vber/common/security/config/SecurityConfig.java

@@ -46,7 +46,10 @@ public class SecurityConfig implements WebMvcConfigurer {
      */
     @Override
     public void addInterceptors(@NonNull InterceptorRegistry registry) {
-        // 注册路由拦截器,自定义验证规则
+        // 获取SSE路径配置
+        String ssePath = SpringUtils.getProperty("sse.path", String.class, "/resource/sse");
+            
+        // 注册路由拦截器,自定义验证规则
         registry.addInterceptor(new SaInterceptor(handler -> {
                     AllUrlHandler allUrlHandler = SpringUtils.getBean(AllUrlHandler.class);
                     // 登录验证 -- 排除多个路径
@@ -66,7 +69,7 @@ public class SecurityConfig implements WebMvcConfigurer {
                                         throw new SseException(e.getMessage(), e.getCode());
                                     }
                                 }
-
+    
                                 // 检查 header 与 param 里的 clientid 与 token 里的是否一致
                                 String headerCid = Objects.requireNonNull(request).getHeader(LoginHelper.CLIENT_KEY);
                                 String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY);
@@ -76,17 +79,19 @@ public class SecurityConfig implements WebMvcConfigurer {
                                     throw NotLoginException.newInstance(StpUtil.getLoginType(), "-100", "客户端ID与Token不匹配",
                                             StpUtil.getTokenValue());
                                 }
-
+    
                                 // 有效率影响 用于临时测试
                                 // if (log.isDebugEnabled()) {
                                 // log.info("剩余有效时间: {}", StpUtil.getTokenTimeout());
                                 // log.info("临时有效时间: {}", StpUtil.getTokenActivityTimeout());
                                 // }
-
+    
                             });
                 })).addPathPatterns("/**")
                 // 排除不需要拦截的路径
-                .excludePathPatterns(Objects.requireNonNull(securityProperties.getExcludes()));
+                .excludePathPatterns(Objects.requireNonNull(securityProperties.getExcludes()))
+                // 排除SSE路径,避免SaToken在异步上下文中出现上下文未初始化问题
+                .excludePathPatterns(ssePath);
     }
 
     /**

+ 10 - 4
SERVER/VberAdminPlusV3/vber-common/vber-common-sse/src/main/java/com/vber/common/sse/controller/SseController.java

@@ -30,12 +30,18 @@ public class SseController implements DisposableBean {
      */
     @GetMapping(value = "${sse.path}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
     public SseEmitter connect() {
-        if (!StpUtil.isLogin()) {
+        // 由于SSE路径已被排除在SaToken拦截器之外,需要手动检查登录状态
+        try {
+            if (!StpUtil.isLogin()) {
+                return null;
+            }
+            String tokenValue = StpUtil.getTokenValue();
+            Long userId = LoginHelper.getUserId();
+            return sseEmitterManager.connect(userId, tokenValue);
+        } catch (Exception e) {
+            // 捕获SaTokenContext未初始化等异常,返回null中断连接
             return null;
         }
-        String tokenValue = StpUtil.getTokenValue();
-        Long userId = LoginHelper.getUserId();
-        return sseEmitterManager.connect(userId, tokenValue);
     }
 
     /**

+ 7 - 1
SERVER/VberAdminPlusV3/vber-common/vber-common-web/src/main/java/com/vber/common/web/handler/GlobalExceptionHandler.java

@@ -147,7 +147,7 @@ public class GlobalExceptionHandler {
      * sse 连接超时异常 不需要处理
      */
     @ExceptionHandler(AsyncRequestTimeoutException.class)
-    public void handleRuntimeException(AsyncRequestTimeoutException e) {
+    public void handleAsyncRequestTimeoutException(AsyncRequestTimeoutException e) {
     }
 
     /**
@@ -156,6 +156,12 @@ public class GlobalExceptionHandler {
     @ExceptionHandler(RuntimeException.class)
     public R<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) {
         String requestURI = request.getRequestURI();
+        // 如果是SSE相关的请求,不返回JSON响应,避免Content-Type冲突
+        if (requestURI != null && requestURI.contains("sse")) {
+            log.debug("SSE请求'{}'发生异常: {}", requestURI, e.getMessage());
+            return null;
+        }
+        // 非SSE请求正常处理
         log.error("请求地址'{}',发生未知异常.", requestURI, e);
         return R.fail("发生未知异常,请联系管理员");
     }