feat: 更新配置文件和代码,优化Swagger文档和负载均衡支持

This commit is contained in:
2026-01-08 01:15:56 +08:00
parent 05aeef2f79
commit fc72acf490
11 changed files with 72 additions and 43 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CoolRequestCommonStatePersistent"> <component name="CoolRequestCommonStatePersistent">
<option name="searchCache" value="系统内部异常" /> <option name="searchCache" value="UserRegisterRequestDTO" />
</component> </component>
</project> </project>

24
.idea/dataSources.xml generated
View File

@@ -25,29 +25,5 @@
<jdbc-url>jdbc:mysql://10.0.0.10/aioj_dev</jdbc-url> <jdbc-url>jdbc:mysql://10.0.0.10/aioj_dev</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir> <working-dir>$ProjectFileDir$</working-dir>
</data-source> </data-source>
<data-source source="LOCAL" name="jdbc:mysql://10.0.0.10/aioj_dev [DEBUG]" group="AIOJAdminApplication" uuid="41a79ccb-ccd0-4180-92f5-e2ef6a45eb88">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://10.0.0.10/aioj_dev</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="jdbc:mysql://10.0.0.10/aioj_dev [DEBUG]" group="AIOJAuthApplication" uuid="25412482-92b5-469f-ab7e-552bb8d40a92">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://10.0.0.10/aioj_dev</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="jdbc:mysql://10.0.0.10/aioj_dev [DEBUG]" group="UserServiceApplication" uuid="b7567e65-352c-4868-8b20-267b4c439f0e">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://10.0.0.10/aioj_dev</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component> </component>
</project> </project>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="db-tree-configuration"> <component name="db-tree-configuration">
<option name="data" value="1:0:AIOJAdminApplication&#10;4:0:UserServiceApplication&#10;7:0:AIOJAuthApplication&#10;----------------------------------------&#10;2:1:43cc61de-66e1-44cc-b4a2-b24d7e03b490&#10;3:1:41a79ccb-ccd0-4180-92f5-e2ef6a45eb88&#10;5:4:903d03c4-df11-4cf8-939a-3e5fba0ab207&#10;6:4:b7567e65-352c-4868-8b20-267b4c439f0e&#10;8:7:2fd8684a-b9aa-4507-abb0-f7c259d91286&#10;9:7:25412482-92b5-469f-ab7e-552bb8d40a92&#10;" /> <option name="data" value="1:0:AIOJAdminApplication&#10;3:0:UserServiceApplication&#10;5:0:AIOJAuthApplication&#10;----------------------------------------&#10;2:1:43cc61de-66e1-44cc-b4a2-b24d7e03b490&#10;4:3:903d03c4-df11-4cf8-939a-3e5fba0ab207&#10;6:5:2fd8684a-b9aa-4507-abb0-f7c259d91286&#10;" />
</component> </component>
</project> </project>

5
.idea/encodings.xml generated
View File

@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Encoding"> <component name="Encoding">
<file url="file://$PROJECT_DIR$/../../../../Windows/System32/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/../../../../Windows/System32/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-ai-service/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-ai-service/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-ai-service/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-ai-service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-auth/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-auth/src/main/java" charset="UTF-8" />
@@ -14,6 +16,7 @@
<file url="file://$PROJECT_DIR$/aioj-backend-common/aioj-backend-common-mybatis/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-common/aioj-backend-common-mybatis/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-common/aioj-backend-common-starter/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-common/aioj-backend-common-starter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-common/aioj-backend-common-starter/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-common/aioj-backend-common-starter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-common/aioj-backend-common-swagger/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-common/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-common/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-common/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/aioj-backend-gateway/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-gateway/src/main/java" charset="UTF-8" />
@@ -33,7 +36,5 @@
<file url="file://$PROJECT_DIR$/aioj-backend-user-service/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/aioj-backend-user-service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/../../../../Windows/System32/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/../../../../Windows/System32/src/main/resources" charset="UTF-8" />
</component> </component>
</project> </project>

View File

@@ -25,7 +25,7 @@ public class SwaggerConfiguration implements ApplicationRunner {
@Bean @Bean
public OpenAPI customerOpenAPI() { public OpenAPI customerOpenAPI() {
return new OpenAPI().info(new Info().title("AIOJ-renz微服务✨") return new OpenAPI().info(new Info().title("AIOJ-认证微服务✨")
.description("用户认证功能") .description("用户认证功能")
.version("v1.0.0") .version("v1.0.0")
.contact(new Contact().name("meowrain").email("meowrain@126.com")) .contact(new Contact().name("meowrain").email("meowrain@126.com"))

View File

@@ -1,5 +1,6 @@
package cn.meowrain.aioj.backend.framework.core.web; package cn.meowrain.aioj.backend.framework.core.web;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@@ -40,6 +41,7 @@ public class Result<T> implements Serializable {
* 返回是否是正确响应 * 返回是否是正确响应
* @return boolean * @return boolean
*/ */
@JsonIgnore
public boolean isSuccess() { public boolean isSuccess() {
return SUCCESS_CODE.equals(code); return SUCCESS_CODE.equals(code);
} }
@@ -48,6 +50,7 @@ public class Result<T> implements Serializable {
* 返回是否是错误响应 * 返回是否是错误响应
* @return boolean * @return boolean
*/ */
@JsonIgnore
public boolean isFail() { public boolean isFail() {
return !isSuccess(); return !isSuccess();
} }

View File

@@ -79,5 +79,9 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -1,6 +1,7 @@
package cn.meowrain.aioj.backend.gateway.config; package cn.meowrain.aioj.backend.gateway.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
@@ -13,9 +14,11 @@ import org.springframework.web.reactive.function.client.WebClient;
public class GatewayConfiguration { public class GatewayConfiguration {
/** /**
* WebClient Bean用于服务间调用 * 支持负载均衡的 WebClient Bean用于服务间调用
* 加上 @LoadBalanced 注解后可以使用 lb://service-name 格式的 URI
*/ */
@Bean @Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() { public WebClient.Builder webClientBuilder() {
return WebClient.builder(); return WebClient.builder();
} }

View File

@@ -0,0 +1,42 @@
package cn.meowrain.aioj.backend.gateway.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
/**
* 启动时打印 Swagger 文档地址
*/
@Slf4j
@Component
public class SwaggerDocPrinter implements ApplicationRunner {
@Value("${server.port:8080}")
private int port;
@Value("${server.servlet.context-path:}")
private String contextPath;
@Override
public void run(ApplicationArguments args) throws Exception {
String ip = InetAddress.getLocalHost().getHostAddress();
String ctx = contextPath == null ? "" : contextPath;
String line = "=".repeat(60);
log.info("\n" + line +
"\n 应用启动成功Swagger 文档地址:" +
"\n" + line +
"\n 本地访问: http://localhost:" + port + ctx + "/doc.html" +
"\n 网络访问: http://" + ip + ":" + port + ctx + "/doc.html" +
"\n" + line +
"\n API 文档资源:" +
"\n - Knife4j UI: http://localhost:" + port + ctx + "/doc.html" +
"\n - Swagger Resources: http://localhost:" + port + ctx + "/swagger-resources" +
"\n" + line);
}
}

View File

@@ -48,19 +48,19 @@ public class AuthGlobalFilter implements GlobalFilter, Ordered {
ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath(); String path = request.getURI().getPath();
log.info("Auth filter processing request: {}", path); log.info("🚀 网关拦截请求: {}", path);
log.info("Loaded white list from config: {}", gatewayPropertiesConfiguration.getWhiteList()); log.debug("📋 白名单配置: {}", gatewayPropertiesConfiguration.getWhiteList());
// 检查是否在白名单中 // 检查是否在白名单中
if (isWhiteListPath(path)) { if (isWhiteListPath(path)) {
log.info("Path {} is in whitelist, skip authentication", path); log.info("✅ 路径 {} 在白名单中,跳过认证", path);
return chain.filter(exchange); return chain.filter(exchange);
} }
// 获取Authorization头 // 获取Authorization头
String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION); String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if (authHeader == null || !authHeader.startsWith("Bearer ")) { if (authHeader == null || !authHeader.startsWith("Bearer ")) {
log.warn("No valid authorization header found for path: {}", path); log.warn("⚠️ 请求缺少有效的 Authorization : {}", path);
return handleUnauthorized(exchange); return handleUnauthorized(exchange);
} }
@@ -70,15 +70,15 @@ public class AuthGlobalFilter implements GlobalFilter, Ordered {
return validateToken(token) return validateToken(token)
.flatMap(isValid -> { .flatMap(isValid -> {
if (isValid) { if (isValid) {
log.info("Token validation successful for path: {}", path); log.info("🔓 Token 验证成功: {}", path);
return chain.filter(exchange); return chain.filter(exchange);
} else { } else {
log.warn("Token validation failed for path: {}", path); log.warn("🔒 Token 验证失败: {}", path);
return handleUnauthorized(exchange); return handleUnauthorized(exchange);
} }
}) })
.onErrorResume(throwable -> { .onErrorResume(throwable -> {
log.error("Token validation error for path: {}", path, throwable); log.error("Token 验证异常: {}", path, throwable);
return handleUnauthorized(exchange); return handleUnauthorized(exchange);
}); });
} }
@@ -105,7 +105,7 @@ public class AuthGlobalFilter implements GlobalFilter, Ordered {
private Mono<Boolean> validateToken(String token) { private Mono<Boolean> validateToken(String token) {
return webClientBuilder.build() return webClientBuilder.build()
.post() .post()
.uri("lb://auth-service/v1/auth/validate") .uri("lb://auth-service/api/v1/auth/validate")
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token) .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.retrieve() .retrieve()
@@ -116,7 +116,7 @@ public class AuthGlobalFilter implements GlobalFilter, Ordered {
Result result = objectMapper.readValue(response, Result.class); Result result = objectMapper.readValue(response, Result.class);
return Objects.equals(result.getCode(), Result.SUCCESS_CODE); return Objects.equals(result.getCode(), Result.SUCCESS_CODE);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Failed to parse auth response", e); log.error("❌ 解析认证服务响应失败", e);
return false; return false;
} }
}) })

View File

@@ -64,11 +64,11 @@ logging:
root: INFO root: INFO
# Nacos 相关日志 # Nacos 相关日志
com.alibaba.nacos: INFO com.alibaba.nacos: INFO
com.alibaba.cloud.nacos: DEBUG com.alibaba.cloud.nacos: INFO
# LoadBalancer 日志 # LoadBalancer 日志
org.springframework.cloud.loadbalancer: DEBUG org.springframework.cloud.loadbalancer: INFO
# Gateway 日志 # Gateway 日志 - 改为 INFO 减少输出,需要调试时改回 DEBUG
org.springframework.cloud.gateway: DEBUG org.springframework.cloud.gateway: INFO
# 自定义过滤器日志 # 自定义过滤器日志
cn.meowrain.aioj.backend.gateway: DEBUG cn.meowrain.aioj.backend.gateway: DEBUG