From 98e94699ae0c80840b845fcfb057b3d35032d13b Mon Sep 17 00:00:00 2001 From: Azure <983547216@qq.com> Date: Tue, 16 Jun 2026 11:47:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0swagger=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=94=B9springboot=E7=89=88=E6=9C=AC=E4=B8=BA3.5.15?= =?UTF-8?q?=EF=BC=8C=E5=8E=BB=E9=99=A4STR=E6=9C=AB=E7=8F=AD=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 22 ++++++++++------ .../common/config/OpenApiConfig.java | 25 +++++++++++++++++++ .../common/config/SaTokenConfigure.java | 4 +++ .../common/utils/RedisCacheUtil.java | 18 ++++++------- .../common/utils/RedisMqUtil.java | 18 ++++++------- src/main/resources/application.yml | 15 ++++++++++- 6 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/webgame/webgamebackend/common/config/OpenApiConfig.java diff --git a/pom.xml b/pom.xml index a9da9cc..237d4e5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 4.1.0 + 3.5.15 @@ -18,14 +18,13 @@ 21 - --enable-preview - + org.springframework.boot - spring-boot-starter-webmvc + spring-boot-starter-web @@ -50,10 +49,10 @@ spring-boot-starter-validation - + org.springframework.boot - spring-boot-starter-aspectj + spring-boot-starter-aop @@ -77,10 +76,10 @@ 5.8.38 - + cn.dev33 - sa-token-spring-boot4-starter + sa-token-spring-boot3-starter 1.45.0 @@ -107,6 +106,13 @@ spring-security-crypto + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.8.17 + + org.springframework.boot diff --git a/src/main/java/com/webgame/webgamebackend/common/config/OpenApiConfig.java b/src/main/java/com/webgame/webgamebackend/common/config/OpenApiConfig.java new file mode 100644 index 0000000..41b667c --- /dev/null +++ b/src/main/java/com/webgame/webgamebackend/common/config/OpenApiConfig.java @@ -0,0 +1,25 @@ +package com.webgame.webgamebackend.common.config; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * OpenAPI / Swagger 接口文档配置 + */ +@Configuration +public class OpenApiConfig { + + /** + * 自定义 OpenAPI 文档基本信息 + */ + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI() + .info(new Info() + .title("WebGame 后端接口文档") + .version("1.0.0") + .description("WebGame 游戏后端 REST API 接口文档")); + } +} diff --git a/src/main/java/com/webgame/webgamebackend/common/config/SaTokenConfigure.java b/src/main/java/com/webgame/webgamebackend/common/config/SaTokenConfigure.java index c940f29..44e52f4 100644 --- a/src/main/java/com/webgame/webgamebackend/common/config/SaTokenConfigure.java +++ b/src/main/java/com/webgame/webgamebackend/common/config/SaTokenConfigure.java @@ -22,6 +22,10 @@ public class SaTokenConfigure implements WebMvcConfigurer { registry.addInterceptor(new SaInterceptor(handler -> { SaRouter.match("/**") .notMatch("/actuator/**") + .notMatch("/swagger-ui/**") + .notMatch("/swagger-ui.html") + .notMatch("/v3/api-docs/**") + .notMatch("/webjars/**") .check(r -> StpUtil.checkLogin()); })).addPathPatterns("/**"); } diff --git a/src/main/java/com/webgame/webgamebackend/common/utils/RedisCacheUtil.java b/src/main/java/com/webgame/webgamebackend/common/utils/RedisCacheUtil.java index e0d7bd4..f0deab2 100644 --- a/src/main/java/com/webgame/webgamebackend/common/utils/RedisCacheUtil.java +++ b/src/main/java/com/webgame/webgamebackend/common/utils/RedisCacheUtil.java @@ -9,8 +9,6 @@ import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; -import static java.lang.StringTemplate.STR; - /** * Redis缓存工具类 */ @@ -71,7 +69,7 @@ public class RedisCacheUtil { try { json = JSON.toJSONString(v); } catch (Exception e) { - log.error(STR."写入缓存失败, 键: \{key}, 原因: \{e.getMessage()}", e); + log.error("写入缓存失败, 键: {}, 原因: {}", key, e.getMessage(), e); return false; } @@ -83,7 +81,7 @@ public class RedisCacheUtil { return true; } catch (Exception e) { - log.error(STR."写入缓存失败, 键: \{key}, 值: \{json}, 原因: \{e.getMessage()}", e); + log.error("写入缓存失败, 键: {}, 值: {}, 原因: {}", key, json, e.getMessage(), e); } return false; } @@ -99,7 +97,7 @@ public class RedisCacheUtil { * @return 是否成功 */ public Boolean cacheValue(String prefix, String k, Object v, long expireTime) { - if (!prefix.endsWith(":")) prefix = STR."\{prefix}:"; + if (!prefix.endsWith(":")) prefix = prefix + ":"; if (k.startsWith(":")) k = k.substring(1); return cacheValue(prefix + k, v, expireTime); } @@ -116,7 +114,7 @@ public class RedisCacheUtil { */ public Boolean cacheValue(String prefix, Long k, Object v, long expireTime) { if (prefix.startsWith(":")) prefix = prefix.substring(1); - if (!prefix.endsWith(":")) prefix = STR."\{prefix}:"; + if (!prefix.endsWith(":")) prefix = prefix + ":"; return cacheValue(prefix + k, v, expireTime); } @@ -182,7 +180,7 @@ public class RedisCacheUtil { */ public T getCache(String prefix, String k, Class cls, long expireTime) { if (prefix.startsWith(":")) prefix = prefix.substring(1); - if (!prefix.endsWith(":")) prefix = STR."\{prefix}:"; + if (!prefix.endsWith(":")) prefix = prefix + ":"; if (k.startsWith(":")) k = k.substring(1); return getCache(prefix + k, cls, expireTime, TimeUnit.MILLISECONDS); } @@ -200,7 +198,7 @@ public class RedisCacheUtil { */ public T getCache(String prefix, Long k, Class cls, long expireTime) { if (prefix.startsWith(":")) prefix = prefix.substring(1); - if (!prefix.endsWith(":")) prefix = STR."\{prefix}:"; + if (!prefix.endsWith(":")) prefix = prefix + ":"; return getCache(prefix + k, cls, expireTime, TimeUnit.MILLISECONDS); } @@ -252,7 +250,7 @@ public class RedisCacheUtil { */ public Boolean removeCache(String prefix, Long k) { if (prefix.startsWith(":")) prefix = prefix.substring(1); - if (!prefix.endsWith(":")) prefix = STR."\{prefix}:"; + if (!prefix.endsWith(":")) prefix = prefix + ":"; return removeCache(prefix + k); } @@ -289,7 +287,7 @@ public class RedisCacheUtil { */ public Boolean removeCache(String prefix, String k) { if (prefix.startsWith(":")) prefix = prefix.substring(1); - if (!prefix.endsWith(":")) prefix = STR."\{prefix}:"; + if (!prefix.endsWith(":")) prefix = prefix + ":"; if (k.startsWith(":")) k = k.substring(1); return removeCache(prefix + k); } diff --git a/src/main/java/com/webgame/webgamebackend/common/utils/RedisMqUtil.java b/src/main/java/com/webgame/webgamebackend/common/utils/RedisMqUtil.java index 7776fbb..ce654b8 100644 --- a/src/main/java/com/webgame/webgamebackend/common/utils/RedisMqUtil.java +++ b/src/main/java/com/webgame/webgamebackend/common/utils/RedisMqUtil.java @@ -31,7 +31,7 @@ public class RedisMqUtil { return; } if (message == null) { - log.warn(STR."[REDIS消息队列] 发布信息至通道(\{channel})失败: 信息体为 null"); + log.warn("[REDIS消息队列] 发布信息至通道({})失败: 信息体为 null", channel); return; } @@ -40,13 +40,13 @@ public class RedisMqUtil { try { json = JSON.toJSONString(message); } catch (Exception e) { - log.warn(STR."[REDIS消息队列] 发布信息至通道(\{channel})异常: 信息实体无法正确的序列化为JSON字符串, \{e.getMessage()}", e); + log.warn("[REDIS消息队列] 发布信息至通道({})异常: 信息实体无法正确的序列化为JSON字符串, {}", channel, e.getMessage(), e); return; } redisTemplate.convertAndSend(channel, json); } catch (Exception e) { - log.warn(STR."[REDIS消息队列] 发布信息至通道(\{channel})异常: \{e.getMessage()}", e); + log.warn("[REDIS消息队列] 发布信息至通道({})异常: {}", channel, e.getMessage(), e); } } @@ -56,12 +56,12 @@ public class RedisMqUtil { return; } if (callback == null) { - log.warn(STR."[REDIS消息队列] 订阅通道(\{channel})失败, 回调方法不可为空"); + log.warn("[REDIS消息队列] 订阅通道({})失败, 回调方法不可为空", channel); return; } try { - var adapter = new MessageListenerAdapter((MessageListener) (message, _) -> { + var adapter = new MessageListenerAdapter((MessageListener) (message, pattern) -> { var body = message.getBody(); var channelName = new String(message.getChannel()); @@ -69,22 +69,22 @@ public class RedisMqUtil { try { dto = JSON.parseObject(new String(body), clazz); } catch (Exception e) { - log.error(STR."[REDIS消息队列] 消费通道(\{channelName})信息实体类型转换处理异常: \{e.getMessage()}, 信息: \{body}", e); + log.error("[REDIS消息队列] 消费通道({})信息实体类型转换处理异常: {}, 信息: {}", channelName, e.getMessage(), body, e); return; } try { callback.accept(dto); } catch (Exception e) { - log.error(STR."[REDIS消息队列] 消费通道(\{channelName})信息回调处理异常: \{e.getMessage()}, 信息: \{body}", e); + log.error("[REDIS消息队列] 消费通道({})信息回调处理异常: {}, 信息: {}", channelName, e.getMessage(), body, e); } }); redisMessageListenerContainer.addMessageListener(adapter, new PatternTopic(channel)); } catch (Exception e) { - log.error(STR."[REDIS消息队列] 订阅通道(\{channel})异常: \{e.getMessage()}", e); + log.error("[REDIS消息队列] 订阅通道({})异常: {}", channel, e.getMessage(), e); return; } - log.info(STR."[REDIS消息队列] 订阅通道(\{channel})成功"); + log.info("[REDIS消息队列] 订阅通道({})成功", channel); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index cc1557e..6a3c785 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -82,4 +82,17 @@ sa-token: # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 - is-log: true \ No newline at end of file + is-log: true + +############## SpringDoc OpenAPI 配置 ############## +springdoc: + api-docs: + # 显式声明启用,消除启动警告(生产环境建议设为 false) + enabled: true + swagger-ui: + enabled: true + path: /swagger-ui.html + # 按标签字母排序 + tags-sorter: alpha + # 请求方法字母排序 + operations-sorter: alpha \ No newline at end of file