diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/BackResultException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/BackResultException.java new file mode 100644 index 00000000..87b2c5ed --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/BackResultException.java @@ -0,0 +1,28 @@ +package cn.dev33.satoken.exception; + +/** + * 一个异常:代表停止匹配,直接退出,向前端输出结果 + * + * @author kong + */ +public class BackResultException extends SaTokenException { + + /** + * 序列化版本号 + */ + private static final long serialVersionUID = 6806129545290130143L; + + /** + * 要输出的结果 + */ + public Object result; + + /** + * 构造 + */ + public BackResultException(Object result) { + super(String.valueOf(result)); + this.result = result; + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java b/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java index 0672dbd6..4419efa6 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java @@ -5,6 +5,7 @@ import java.util.List; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.exception.BackResultException; import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.fun.IsRunFunction; import cn.dev33.satoken.fun.SaFunction; @@ -134,8 +135,20 @@ public class SaRouter { public static void stop() { throw new StopMatchException(); } - - - + + /** + * 停止匹配,结束执行,向前端返回结果 + * @param result 要输出的结果 + */ + public static void back(Object result) { + throw new BackResultException(result); + } + + /** + * 停止匹配,结束执行,向前端返回结果 + */ + public static void back() { + throw new BackResultException(""); + } } diff --git a/sa-token-demo/sa-token-demo-solon/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-solon/src/main/resources/application.yml index bf9c4f97..055d40e7 100644 --- a/sa-token-demo/sa-token-demo-solon/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-solon/src/main/resources/application.yml @@ -2,24 +2,24 @@ server: port: 8081 -solon: - # sa-token配置 - sa-token: - # token名称 (同时也是cookie名称) - token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 - timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) - allow-concurrent-login: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) - is-share: true - # token风格 - token-style: uuid - # 是否输出操作日志 - is-log: false - +# sa-token配置 +sa-token: + # token名称 (同时也是cookie名称) + token-name: satoken + # token有效期,单位s 默认30天, -1代表永不过期 + timeout: 2592000 + # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 + activity-timeout: -1 + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + allow-concurrent-login: true + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + is-share: true + # token风格 + token-style: uuid + # 是否输出操作日志 + is-log: false + +solon: # redis配置 redis: # Redis数据库索引(默认为0) diff --git a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java index d024c158..3da66ead 100644 --- a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java +++ b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java @@ -18,4 +18,4 @@ public class SaTokenDemoApplication { System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); } -} \ No newline at end of file +} diff --git a/sa-token-doc/doc/use/route-check.md b/sa-token-doc/doc/use/route-check.md index b7bdde34..16a6ff19 100644 --- a/sa-token-doc/doc/use/route-check.md +++ b/sa-token-doc/doc/use/route-check.md @@ -116,6 +116,13 @@ registry.addInterceptor(new SaRouteInterceptor((req, res, handler) -> { ``` 如上示例,代码运行至第2条匹配链时,会在stop函数处提前退出整个匹配函数,从而忽略掉剩余的所有match匹配 +除了`stop()`函数,`SaRouter`还提供了 `SaRouter.back()` 函数,用于:停止匹配,结束执行,直接向前端返回结果 +``` java +SaRouter.match("/user/back", () -> SaRouter.back("执行back函数后将停止匹配,也不会进入Controller,而是直接将此参数作为返回值输出到前端")); +``` + + + diff --git a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java index b36f0350..ff241449 100644 --- a/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java +++ b/sa-token-starter/sa-token-reactor-spring-boot-starter/src/main/java/cn/dev33/satoken/reactor/filter/SaReactorFilter.java @@ -9,6 +9,7 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; +import cn.dev33.satoken.exception.BackResultException; import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.filter.SaFilterAuthStrategy; @@ -165,14 +166,13 @@ public class SaReactorFilter implements WebFilter { } catch (Throwable e) { // 1. 获取异常处理策略结果 - Object result = error.run(e); - String resultString = String.valueOf(result); + String result = (e instanceof BackResultException) ? e.getMessage() : String.valueOf(error.run(e)); // 2. 写入输出流 if(exchange.getResponse().getHeaders().getFirst("Content-Type") == null) { exchange.getResponse().getHeaders().set("Content-Type", "text/plain; charset=utf-8"); } - return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(resultString.getBytes()))); + return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(result.getBytes()))); } finally { // 清除上下文 diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java index 8d712f6f..208aa442 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/XPluginImp.java @@ -35,7 +35,7 @@ public class XPluginImp implements Plugin { //集成初始化 //注入配置Bean - SaTokenConfig saTokenConfig = Solon.cfg().getBean("solon.sa-token", SaTokenConfig.class); + SaTokenConfig saTokenConfig = Solon.cfg().getBean("sa-token", SaTokenConfig.class); SaManager.setConfig(saTokenConfig); diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java index c6c10647..60c6233d 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/integration/SaTokenPathFilter.java @@ -1,6 +1,7 @@ package cn.dev33.satoken.solon.integration; +import cn.dev33.satoken.exception.BackResultException; import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.filter.SaFilterAuthStrategy; @@ -150,13 +151,12 @@ public class SaTokenPathFilter implements Filter { } catch (StopMatchException e) { } catch (Throwable e) { - // 1. 获取异常处理策略结果 - Object result = error.run(e); - String resultString = String.valueOf(result); + // 1. 获取异常处理策略结果 + String result = (e instanceof BackResultException) ? e.getMessage() : String.valueOf(error.run(e)); // 2. 写入输出流 ctx.contentType("text/plain; charset=utf-8"); - ctx.output(resultString); + ctx.output(result); return; } diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java index 8c700769..46eb59e8 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/filter/SaServletFilter.java @@ -14,6 +14,7 @@ import javax.servlet.ServletResponse; import org.springframework.core.annotation.Order; +import cn.dev33.satoken.exception.BackResultException; import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.router.SaRouter; @@ -163,14 +164,13 @@ public class SaServletFilter implements Filter { } catch (Throwable e) { // 1. 获取异常处理策略结果 - Object result = error.run(e); - String resultString = String.valueOf(result); + String result = (e instanceof BackResultException) ? e.getMessage() : String.valueOf(error.run(e)); // 2. 写入输出流 if(response.getContentType() == null) { response.setContentType("text/plain; charset=utf-8"); } - response.getWriter().print(resultString); + response.getWriter().print(result); return; } diff --git a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java index 6d686b49..7a08e433 100644 --- a/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java +++ b/sa-token-starter/sa-token-spring-boot-starter/src/main/java/cn/dev33/satoken/interceptor/SaRouteInterceptor.java @@ -5,6 +5,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; +import cn.dev33.satoken.exception.BackResultException; import cn.dev33.satoken.exception.StopMatchException; import cn.dev33.satoken.router.SaRouteFunction; import cn.dev33.satoken.servlet.model.SaRequestForServlet; @@ -63,6 +64,14 @@ public class SaRouteInterceptor implements HandlerInterceptor { try { function.run(new SaRequestForServlet(request), new SaResponseForServlet(response), handler); } catch (StopMatchException e) { + // 停止匹配,进入Controller + } catch (BackResultException e) { + // 停止匹配,向前端输出结果 + if(response.getContentType() == null) { + response.setContentType("text/plain; charset=utf-8"); + } + response.getWriter().print(e.getMessage()); + return false; } }