fix: 修复网关启动找不到服务的问题,修复jwt问题,修复自动导入失败问题。
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cn.meowrain</groupId>
|
||||
@@ -63,5 +63,9 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -14,43 +14,47 @@ import java.time.format.DateTimeFormatter;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class BannerApplicationRunner implements ApplicationRunner {
|
||||
private final Environment env;
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
// Active profiles
|
||||
String profiles = String.join(",", env.getActiveProfiles());
|
||||
if (profiles.isEmpty()) {
|
||||
profiles = "default";
|
||||
}
|
||||
private final Environment env;
|
||||
|
||||
// Port
|
||||
String port = env.getProperty("server.port", "unknown");
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
// JVM info
|
||||
String jvm = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
// Active profiles
|
||||
String profiles = String.join(",", env.getActiveProfiles());
|
||||
if (profiles.isEmpty()) {
|
||||
profiles = "default";
|
||||
}
|
||||
|
||||
// PID
|
||||
String pid = ManagementFactory.getRuntimeMXBean().getPid() + "";
|
||||
// Port
|
||||
String port = env.getProperty("server.port", "unknown");
|
||||
|
||||
// Time
|
||||
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
// JVM info
|
||||
String jvm = System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ")";
|
||||
|
||||
// Git commit id (如果没有 git.properties,不会报错)
|
||||
String gitCommit = env.getProperty("git.commit.id.abbrev", "N/A");
|
||||
// PID
|
||||
String pid = ManagementFactory.getRuntimeMXBean().getPid() + "";
|
||||
|
||||
printBanner(appName, profiles, port, jvm, pid, time, gitCommit);
|
||||
}
|
||||
private void printBanner(String appName, String profiles, String port, String jvm, String pid, String time,
|
||||
String gitCommit) {
|
||||
// Time
|
||||
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
// Git commit id (如果没有 git.properties,不会报错)
|
||||
String gitCommit = env.getProperty("git.commit.id.abbrev", "N/A");
|
||||
|
||||
printBanner(appName, profiles, port, jvm, pid, time, gitCommit);
|
||||
}
|
||||
|
||||
private void printBanner(String appName, String profiles, String port, String jvm, String pid, String time,
|
||||
String gitCommit) {
|
||||
|
||||
String banner = "\n" + "------------------------------------------------------------\n"
|
||||
+ " ✨AI Online Judge✨ - " + appName + "\n" + " Environment : " + profiles + "\n" + " Port : "
|
||||
+ port + "\n" + " Git Commit : " + gitCommit + "\n" + " JVM : " + jvm + "\n"
|
||||
+ " PID : " + pid + "\n" + " Started At : " + time + "\n"
|
||||
+ "------------------------------------------------------------\n";
|
||||
System.out.println(banner);
|
||||
}
|
||||
|
||||
String banner = "\n" + "------------------------------------------------------------\n"
|
||||
+ " ✨AI Online Judge✨ - " + appName + "\n" + " Environment : " + profiles + "\n" + " Port : "
|
||||
+ port + "\n" + " Git Commit : " + gitCommit + "\n" + " JVM : " + jvm + "\n"
|
||||
+ " PID : " + pid + "\n" + " Started At : " + time + "\n"
|
||||
+ "------------------------------------------------------------\n";
|
||||
System.out.println(banner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@ import org.springframework.core.env.Environment;
|
||||
|
||||
@AutoConfiguration
|
||||
public class AIOJBannerAutoConfiguration {
|
||||
@Bean
|
||||
public BannerApplicationRunner bannerApplicationRunner(Environment env) {
|
||||
return new BannerApplicationRunner(env);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BannerApplicationRunner bannerApplicationRunner(Environment env) {
|
||||
return new BannerApplicationRunner(env);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,18 +4,20 @@ package cn.meowrain.aioj.backend.framework.core.constants;
|
||||
* 全局服务名称
|
||||
*/
|
||||
public class ServiceNameConstants {
|
||||
/**
|
||||
* 用户服务 SERVICE NAME
|
||||
*/
|
||||
public static final String USER_SERVICE = "user-service";
|
||||
|
||||
/**
|
||||
* 认证服务 SERVICE NAME
|
||||
*/
|
||||
public static final String AUTH_SERVICE = "auth-service";
|
||||
/**
|
||||
* 用户服务 SERVICE NAME
|
||||
*/
|
||||
public static final String USER_SERVICE = "user-service";
|
||||
|
||||
/**
|
||||
* 认证服务 SERVICE NAME
|
||||
*/
|
||||
public static final String AUTH_SERVICE = "auth-service";
|
||||
|
||||
/**
|
||||
* UPMS模块
|
||||
*/
|
||||
public static final String UPMS_SERVICE = "upms-service";
|
||||
|
||||
/**
|
||||
* UPMS模块
|
||||
*/
|
||||
public static final String UPMS_SERVICE = "upms-service";
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import cn.meowrain.aioj.backend.framework.core.web.Result;
|
||||
import cn.meowrain.aioj.backend.framework.core.web.Results;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.FieldError;
|
||||
@@ -12,6 +14,8 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -19,12 +23,18 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class GlobalExceptionHandler {
|
||||
// 加这个构造器,启动看日志
|
||||
public GlobalExceptionHandler() {
|
||||
System.out.println("===== 自定义异常处理器已加载 =====");
|
||||
}
|
||||
|
||||
/**
|
||||
* 捕获所有参数错误,然后统一捕获并且抛出
|
||||
*
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link org.springframework.validation.method.MethodValidationException}
|
||||
* @param ex {@link org.springframework.validation.method.MethodValidationException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = MethodArgumentNotValidException.class)
|
||||
@@ -32,9 +42,9 @@ public class GlobalExceptionHandler {
|
||||
BindingResult bindingResult = ex.getBindingResult();
|
||||
// 收集所有错误字段
|
||||
List<String> errorMessages = bindingResult.getFieldErrors()
|
||||
.stream()
|
||||
.map(FieldError::getDefaultMessage)
|
||||
.toList();
|
||||
.stream()
|
||||
.map(FieldError::getDefaultMessage)
|
||||
.toList();
|
||||
String exceptionMessage = String.join(",", errorMessages);
|
||||
log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionMessage);
|
||||
return Results.paramsValidFailure();
|
||||
@@ -42,8 +52,9 @@ public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 抽象异常捕获其
|
||||
*
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @param ex {@link AbstractException}
|
||||
* @param ex {@link AbstractException}
|
||||
* @return {@link Result<Void>}
|
||||
*/
|
||||
@ExceptionHandler(value = { AbstractException.class })
|
||||
@@ -74,6 +85,7 @@ public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 获取请求URL
|
||||
*
|
||||
* @param request {@link HttpServletRequest}
|
||||
* @return String
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,6 @@ import java.io.Serial;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
|
||||
public class JavaTimeModule extends SimpleModule {
|
||||
|
||||
@Serial
|
||||
@@ -19,7 +18,7 @@ public class JavaTimeModule extends SimpleModule {
|
||||
/**
|
||||
* JavaTimeModule构造函数,用于初始化时间序列化和反序列化规则
|
||||
*/
|
||||
public JavaTimeModule() {
|
||||
public JavaTimeModule() {
|
||||
super(PackageVersion.VERSION);
|
||||
|
||||
// ======================= 时间序列化规则 ===============================
|
||||
|
||||
@@ -13,65 +13,69 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SpringContextHolder implements ApplicationContextAware, EnvironmentAware, DisposableBean {
|
||||
private static ApplicationContext applicationContext = null;
|
||||
public class SpringContextHolder implements ApplicationContextAware, EnvironmentAware, DisposableBean {
|
||||
|
||||
private static Environment environment = null;
|
||||
/**
|
||||
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(String name) {
|
||||
return (T) applicationContext.getBean(name);
|
||||
}
|
||||
private static ApplicationContext applicationContext = null;
|
||||
|
||||
/**
|
||||
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(Class<T> requiredType) {
|
||||
return applicationContext.getBean(requiredType);
|
||||
}
|
||||
private static Environment environment = null;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void destroy() throws Exception {
|
||||
clearHolder();
|
||||
}
|
||||
/**
|
||||
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(String name) {
|
||||
return (T) applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
SpringContextHolder.applicationContext = applicationContext;
|
||||
}
|
||||
/**
|
||||
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
*/
|
||||
public static <T> T getBean(Class<T> requiredType) {
|
||||
return applicationContext.getBean(requiredType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
SpringContextHolder.environment = environment;
|
||||
}
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void destroy() throws Exception {
|
||||
clearHolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除SpringContextHolder中的ApplicationContext为Null.
|
||||
*/
|
||||
public static void clearHolder() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
}
|
||||
applicationContext = null;
|
||||
}
|
||||
/**
|
||||
* 发布事件
|
||||
* @param event
|
||||
*/
|
||||
public static void publishEvent(ApplicationEvent event) {
|
||||
if (applicationContext == null) {
|
||||
return;
|
||||
}
|
||||
applicationContext.publishEvent(event);
|
||||
}
|
||||
/**
|
||||
* 是否是微服务
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isMicro() {
|
||||
return environment.getProperty("spring.cloud.nacos.discovery.enabled", Boolean.class, true);
|
||||
}
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
SpringContextHolder.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
SpringContextHolder.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除SpringContextHolder中的ApplicationContext为Null.
|
||||
*/
|
||||
public static void clearHolder() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
}
|
||||
applicationContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布事件
|
||||
* @param event
|
||||
*/
|
||||
public static void publishEvent(ApplicationEvent event) {
|
||||
if (applicationContext == null) {
|
||||
return;
|
||||
}
|
||||
applicationContext.publishEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是微服务
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isMicro() {
|
||||
return environment.getProperty("spring.cloud.nacos.discovery.enabled", Boolean.class, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
|
||||
@AutoConfiguration
|
||||
public class FeignAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -9,5 +9,7 @@ import java.lang.annotation.*;
|
||||
@Documented
|
||||
@EnableFeignClients
|
||||
public @interface EnableAIOJFeignClients {
|
||||
String[] basePackages() default {};
|
||||
|
||||
String[] basePackages() default {};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.expression.EvaluationContext;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogAspect {
|
||||
|
||||
/**
|
||||
* 环绕通知方法,用于处理系统日志记录
|
||||
* @param point 连接点对象
|
||||
@@ -29,7 +30,7 @@ public class SysLogAspect {
|
||||
*/
|
||||
@Around("@annotation(sysLog)")
|
||||
@SneakyThrows
|
||||
public Object around(ProceedingJoinPoint point,SysLog sysLog) {
|
||||
public Object around(ProceedingJoinPoint point, SysLog sysLog) {
|
||||
String strClassName = point.getTarget().getClass().getName();
|
||||
String strMethodName = point.getSignature().getName();
|
||||
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
|
||||
@@ -76,4 +77,5 @@ public class SysLogAspect {
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,11 +24,10 @@ public class AIOJLogPropertiesConfiguration {
|
||||
*/
|
||||
private Integer maxLength = 20000;
|
||||
|
||||
/**
|
||||
* 放行字段,password,mobile,idcard,phone
|
||||
*/
|
||||
@Value("${log.exclude-fields:password,mobile,idcard,phone}")
|
||||
private List<String> excludeFields;
|
||||
|
||||
/**
|
||||
* 放行字段,password,mobile,idcard,phone
|
||||
*/
|
||||
@Value("${log.exclude-fields:password,mobile,idcard,phone}")
|
||||
private List<String> excludeFields;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.aioj.backend.framework.log.event;
|
||||
|
||||
|
||||
import cn.meowrain.aioj.backend.upms.api.entity.SysLog;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
|
||||
@@ -38,38 +38,40 @@ public class SysLogListener implements InitializingBean {
|
||||
SysLog sysLog = new SysLog();
|
||||
BeanUtils.copyProperties(source, sysLog);
|
||||
|
||||
// json 格式刷参数放在异步中处理,提升性能
|
||||
if (Objects.nonNull(source.getBody())) {
|
||||
String params = objectMapper.writeValueAsString(source.getBody());
|
||||
sysLog.setParams(StrUtil.subPre(params, logProperties.getMaxLength()));
|
||||
}
|
||||
// json 格式刷参数放在异步中处理,提升性能
|
||||
if (Objects.nonNull(source.getBody())) {
|
||||
String params = objectMapper.writeValueAsString(source.getBody());
|
||||
sysLog.setParams(StrUtil.subPre(params, logProperties.getMaxLength()));
|
||||
}
|
||||
|
||||
remoteLogService.saveLog(sysLog);
|
||||
remoteLogService.saveLog(sysLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 Bean 初始化后执行,用于初始化 ObjectMapper
|
||||
* @throws Exception
|
||||
*/
|
||||
/**
|
||||
* 在 Bean 初始化后执行,用于初始化 ObjectMapper
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
//给 ObjectMapper 添加 MixIn(用于过滤字段)
|
||||
objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class);
|
||||
String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]);
|
||||
// 给 ObjectMapper 添加 MixIn(用于过滤字段)
|
||||
objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class);
|
||||
String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]);
|
||||
|
||||
FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name",
|
||||
SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
|
||||
objectMapper.setFilterProvider(filters);
|
||||
objectMapper.registerModule(new JavaTimeModule());
|
||||
}
|
||||
|
||||
/**
|
||||
* 属性过滤混合类:用于通过名称过滤属性
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2025/05/31
|
||||
*/
|
||||
@JsonFilter("filter properties by name")
|
||||
class PropertyFilterMixIn {
|
||||
|
||||
FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name",
|
||||
SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
|
||||
objectMapper.setFilterProvider(filters);
|
||||
objectMapper.registerModule(new JavaTimeModule());
|
||||
}
|
||||
/**
|
||||
* 属性过滤混合类:用于通过名称过滤属性
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2025/05/31
|
||||
*/
|
||||
@JsonFilter("filter properties by name")
|
||||
class PropertyFilterMixIn {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,13 @@ import java.util.Objects;
|
||||
|
||||
public final class SysLogUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统日志事件源
|
||||
* @return 系统日志事件源对象
|
||||
*/
|
||||
public static SysLogEventSource getSysLog() {
|
||||
public static SysLogEventSource getSysLog() {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects
|
||||
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
SysLogEventSource sysLog = new SysLogEventSource();
|
||||
sysLog.setLogType(LogTypeEnum.NORMAL.getType());
|
||||
sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
|
||||
@@ -47,7 +46,8 @@ public final class SysLogUtils {
|
||||
sysLog.setServiceId(SpringUtil.getProperty("spring.application.name"));
|
||||
|
||||
// get 参数脱敏
|
||||
AIOJLogPropertiesConfiguration logProperties = SpringContextHolder.getBean(AIOJLogPropertiesConfiguration.class);
|
||||
AIOJLogPropertiesConfiguration logProperties = SpringContextHolder
|
||||
.getBean(AIOJLogPropertiesConfiguration.class);
|
||||
Map<String, String[]> paramsMap = MapUtil.removeAny(new HashMap<>(request.getParameterMap()),
|
||||
ArrayUtil.toArray(logProperties.getExcludeFields(), String.class));
|
||||
sysLog.setParams(HttpUtil.toParams(paramsMap));
|
||||
@@ -74,7 +74,7 @@ public final class SysLogUtils {
|
||||
* @param <T> 返回泛型
|
||||
* @return 参数值
|
||||
*/
|
||||
public static <T> T getValue(EvaluationContext context, String key, Class<T> clazz) {
|
||||
public static <T> T getValue(EvaluationContext context, String key, Class<T> clazz) {
|
||||
SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
|
||||
Expression expression = spelExpressionParser.parseExpression(key);
|
||||
return expression.getValue(context, clazz);
|
||||
|
||||
Reference in New Issue
Block a user