mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-03-18 03:32:02 +08:00
update 不兼容整体升级 springboot 4.X
update springboot 3.5 => 4.0 update springdoc 2.8 => 3.0 update mybatis-plus 3.5.14 => 3.5.15 update redisson 3.52.0 => 4.1.0 update dynamic-ds 4.3.1 => 4.5.0
This commit is contained in:
@@ -35,7 +35,6 @@ MaxKey 业界领先单点登录产品 - https://gitee.com/dromara/MaxKey <br>
|
|||||||
CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow <br>
|
CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow <br>
|
||||||
数舵科技 软件定制开发APP小程序等 - http://www.shuduokeji.com/ <br>
|
数舵科技 软件定制开发APP小程序等 - http://www.shuduokeji.com/ <br>
|
||||||
引迈信息 软件开发平台 - https://www.jnpfsoft.com/index.html?from=plus-doc <br>
|
引迈信息 软件开发平台 - https://www.jnpfsoft.com/index.html?from=plus-doc <br>
|
||||||
<font color="red">**启山商城系统 多租户商城源码可免费商用可二次开发 - https://www.73app.cn/** </font><br>
|
|
||||||
Mall4J 高质量Java商城系统 - https://www.mall4j.com/cn/?statId=11 <br>
|
Mall4J 高质量Java商城系统 - https://www.mall4j.com/cn/?statId=11 <br>
|
||||||
aizuda flowlong 工作流 - https://gitee.com/aizuda/flowlong <br>
|
aizuda flowlong 工作流 - https://gitee.com/aizuda/flowlong <br>
|
||||||
Ruoyi-Plus-Uniapp - https://ruoyi.plus <br>
|
Ruoyi-Plus-Uniapp - https://ruoyi.plus <br>
|
||||||
|
|||||||
16
pom.xml
16
pom.xml
@@ -14,23 +14,23 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>5.5.2</revision>
|
<revision>5.5.2</revision>
|
||||||
<spring-boot.version>3.5.9</spring-boot.version>
|
<spring-boot.version>4.0.1</spring-boot.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<mybatis.version>3.5.16</mybatis.version>
|
<mybatis.version>3.5.16</mybatis.version>
|
||||||
<springdoc.version>2.8.14</springdoc.version>
|
<springdoc.version>3.0.1</springdoc.version>
|
||||||
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
|
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
|
||||||
<fastexcel.version>1.3.0</fastexcel.version>
|
<fastexcel.version>1.3.0</fastexcel.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<satoken.version>1.44.0</satoken.version>
|
<satoken.version>1.44.0</satoken.version>
|
||||||
<mybatis-plus.version>3.5.14</mybatis-plus.version>
|
<mybatis-plus.version>3.5.15</mybatis-plus.version>
|
||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<hutool.version>5.8.40</hutool.version>
|
<hutool.version>5.8.40</hutool.version>
|
||||||
<spring-boot-admin.version>3.5.5</spring-boot-admin.version>
|
<spring-boot-admin.version>3.5.6</spring-boot-admin.version>
|
||||||
<redisson.version>3.52.0</redisson.version>
|
<redisson.version>4.1.0</redisson.version>
|
||||||
<lock4j.version>2.2.7</lock4j.version>
|
<lock4j.version>2.2.7</lock4j.version>
|
||||||
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
<dynamic-ds.version>4.5.0</dynamic-ds.version>
|
||||||
<snailjob.version>1.9.0</snailjob.version>
|
<snailjob.version>1.9.0</snailjob.version>
|
||||||
<mapstruct-plus.version>1.5.0</mapstruct-plus.version>
|
<mapstruct-plus.version>1.5.0</mapstruct-plus.version>
|
||||||
<mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
|
<mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
<!-- dynamic-datasource 多数据源-->
|
<!-- dynamic-datasource 多数据源-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
<artifactId>dynamic-datasource-spring-boot4-starter</artifactId>
|
||||||
<version>${dynamic-ds.version}</version>
|
<version>${dynamic-ds.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
<artifactId>mybatis-plus-spring-boot4-starter</artifactId>
|
||||||
<version>${mybatis-plus.version}</version>
|
<version>${mybatis-plus.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -5,20 +5,15 @@ server:
|
|||||||
servlet:
|
servlet:
|
||||||
# 应用的访问路径
|
# 应用的访问路径
|
||||||
context-path: /
|
context-path: /
|
||||||
# undertow 配置
|
# jetty 配置
|
||||||
undertow:
|
jetty:
|
||||||
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
|
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
|
||||||
max-http-post-size: -1
|
max-http-form-post-size: -1
|
||||||
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
|
|
||||||
# 每块buffer的空间大小,越小的空间被利用越充分
|
|
||||||
buffer-size: 512
|
|
||||||
# 是否分配的直接内存
|
|
||||||
direct-buffers: true
|
|
||||||
threads:
|
threads:
|
||||||
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
|
# 最小线程数
|
||||||
io: 8
|
min: 8
|
||||||
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
|
# 最大线程数
|
||||||
worker: 256
|
max: 256
|
||||||
|
|
||||||
captcha:
|
captcha:
|
||||||
# 是否启用验证码校验
|
# 是否启用验证码校验
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-aop</artifactId>
|
<artifactId>spring-boot-starter-aspectj</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--常用工具类 -->
|
<!--常用工具类 -->
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package org.dromara.common.core.config;
|
|||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
import org.hibernate.validator.HibernateValidator;
|
import org.hibernate.validator.HibernateValidator;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
|
import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration;
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package org.dromara.common.core.utils;
|
|||||||
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.autoconfigure.thread.Threading;
|
import org.springframework.boot.thread.Threading;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
<artifactId>ruoyi-common-core</artifactId>
|
<artifactId>ruoyi-common-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-web-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springdoc</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
|
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import org.springdoc.core.utils.PropertyResolverUtils;
|
|||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.web.server.autoconfigure.ServerProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
<artifactId>mybatis-plus-spring-boot4-starter</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
|||||||
@@ -21,15 +21,9 @@
|
|||||||
<artifactId>ruoyi-common-core</artifactId>
|
<artifactId>ruoyi-common-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- JSON工具类 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>spring-boot-starter-jackson</artifactId>
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
package org.dromara.common.json.config;
|
package org.dromara.common.json.config;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.Module;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.json.handler.BigNumberSerializer;
|
import org.dromara.common.json.handler.BigNumberSerializer;
|
||||||
import org.dromara.common.json.handler.CustomDateDeserializer;
|
import org.dromara.common.json.handler.CustomDateDeserializer;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import tools.jackson.databind.ext.javatime.deser.LocalDateTimeDeserializer;
|
||||||
|
import tools.jackson.databind.ext.javatime.ser.LocalDateTimeSerializer;
|
||||||
|
import tools.jackson.databind.module.SimpleModule;
|
||||||
|
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@@ -30,24 +29,24 @@ import java.util.TimeZone;
|
|||||||
public class JacksonConfig {
|
public class JacksonConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Module registerJavaTimeModule() {
|
public SimpleModule registerJavaTimeModule() {
|
||||||
// 全局配置序列化返回 JSON 处理
|
// 全局配置序列化返回 JSON 处理
|
||||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
SimpleModule module = new SimpleModule();
|
||||||
javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
|
module.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
|
||||||
javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
|
module.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
|
||||||
javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
|
module.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
|
||||||
javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
|
module.addSerializer(BigDecimal.class, ToStringSerializer.instance);
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
|
module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
|
||||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
|
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
|
||||||
javaTimeModule.addDeserializer(Date.class, new CustomDateDeserializer());
|
module.addDeserializer(Date.class, new CustomDateDeserializer());
|
||||||
return javaTimeModule;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Jackson2ObjectMapperBuilderCustomizer customizer() {
|
public JsonMapperBuilderCustomizer jsonInitCustomizer() {
|
||||||
return builder -> {
|
return builder -> {
|
||||||
builder.timeZone(TimeZone.getDefault());
|
builder.defaultTimeZone(TimeZone.getDefault());
|
||||||
log.info("初始化 jackson 配置");
|
log.info("初始化 jackson 配置");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package org.dromara.common.json.handler;
|
package org.dromara.common.json.handler;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import tools.jackson.core.JsonGenerator;
|
||||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
import tools.jackson.databind.SerializationContext;
|
||||||
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
|
import tools.jackson.databind.annotation.JacksonStdImpl;
|
||||||
import com.fasterxml.jackson.databind.ser.std.NumberSerializer;
|
import tools.jackson.databind.ser.jdk.NumberSerializer;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 超出 JS 最大最小值 处理
|
* 超出 JS 最大最小值 处理
|
||||||
@@ -31,7 +29,7 @@ public class BigNumberSerializer extends NumberSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
public void serialize(Number value, JsonGenerator gen, SerializationContext provider) {
|
||||||
// 超出范围 序列化为字符串
|
// 超出范围 序列化为字符串
|
||||||
if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
|
if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
|
||||||
super.serialize(value, gen, provider);
|
super.serialize(value, gen, provider);
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ package org.dromara.common.json.handler;
|
|||||||
|
|
||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
|
||||||
import org.dromara.common.core.utils.ObjectUtils;
|
import org.dromara.common.core.utils.ObjectUtils;
|
||||||
|
import tools.jackson.core.JsonParser;
|
||||||
|
import tools.jackson.databind.DeserializationContext;
|
||||||
|
import tools.jackson.databind.ValueDeserializer;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,7 +14,7 @@ import java.util.Date;
|
|||||||
*
|
*
|
||||||
* @author AprilWind
|
* @author AprilWind
|
||||||
*/
|
*/
|
||||||
public class CustomDateDeserializer extends JsonDeserializer<Date> {
|
public class CustomDateDeserializer extends ValueDeserializer<Date> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反序列化逻辑:将字符串转换为 Date 对象
|
* 反序列化逻辑:将字符串转换为 Date 对象
|
||||||
@@ -23,10 +22,9 @@ public class CustomDateDeserializer extends JsonDeserializer<Date> {
|
|||||||
* @param p JSON 解析器,用于获取字符串值
|
* @param p JSON 解析器,用于获取字符串值
|
||||||
* @param ctxt 上下文环境(可用于获取更多配置)
|
* @param ctxt 上下文环境(可用于获取更多配置)
|
||||||
* @return 转换后的 Date 对象,若为空字符串返回 null
|
* @return 转换后的 Date 对象,若为空字符串返回 null
|
||||||
* @throws IOException 当字符串格式非法或转换失败时抛出
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
public Date deserialize(JsonParser p, DeserializationContext ctxt) {
|
||||||
DateTime parse = DateUtil.parse(p.getText());
|
DateTime parse = DateUtil.parse(p.getText());
|
||||||
if (ObjectUtils.isNull(parse)) {
|
if (ObjectUtils.isNull(parse)) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -3,32 +3,29 @@ package org.dromara.common.json.utils;
|
|||||||
import cn.hutool.core.lang.Dict;
|
import cn.hutool.core.lang.Dict;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
|
import tools.jackson.core.type.TypeReference;
|
||||||
|
import tools.jackson.databind.JsonNode;
|
||||||
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON 工具类
|
* JSON 工具类
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class JsonUtils {
|
public class JsonUtils {
|
||||||
|
|
||||||
private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);
|
private static final JsonMapper JSON_MAPPER = SpringUtils.getBean(JsonMapper.class);
|
||||||
|
|
||||||
public static ObjectMapper getObjectMapper() {
|
public static JsonMapper getJsonMapper() {
|
||||||
return OBJECT_MAPPER;
|
return JSON_MAPPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,11 +39,7 @@ public class JsonUtils {
|
|||||||
if (ObjectUtil.isNull(object)) {
|
if (ObjectUtil.isNull(object)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return JSON_MAPPER.writeValueAsString(object);
|
||||||
return OBJECT_MAPPER.writeValueAsString(object);
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,11 +55,7 @@ public class JsonUtils {
|
|||||||
if (StringUtils.isEmpty(text)) {
|
if (StringUtils.isEmpty(text)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return JSON_MAPPER.readValue(text, clazz);
|
||||||
return OBJECT_MAPPER.readValue(text, clazz);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,11 +71,7 @@ public class JsonUtils {
|
|||||||
if (ArrayUtil.isEmpty(bytes)) {
|
if (ArrayUtil.isEmpty(bytes)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return JSON_MAPPER.readValue(bytes, clazz);
|
||||||
return OBJECT_MAPPER.readValue(bytes, clazz);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,11 +87,7 @@ public class JsonUtils {
|
|||||||
if (StringUtils.isBlank(text)) {
|
if (StringUtils.isBlank(text)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return JSON_MAPPER.readValue(text, typeReference);
|
||||||
return OBJECT_MAPPER.readValue(text, typeReference);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,14 +101,7 @@ public class JsonUtils {
|
|||||||
if (StringUtils.isBlank(text)) {
|
if (StringUtils.isBlank(text)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return JSON_MAPPER.readValue(text, JSON_MAPPER.getTypeFactory().constructType(Dict.class));
|
||||||
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class));
|
|
||||||
} catch (MismatchedInputException e) {
|
|
||||||
// 类型不匹配说明不是json
|
|
||||||
return null;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,11 +115,7 @@ public class JsonUtils {
|
|||||||
if (StringUtils.isBlank(text)) {
|
if (StringUtils.isBlank(text)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return JSON_MAPPER.readValue(text, JSON_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
|
||||||
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,11 +131,7 @@ public class JsonUtils {
|
|||||||
if (StringUtils.isEmpty(text)) {
|
if (StringUtils.isEmpty(text)) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
try {
|
return JSON_MAPPER.readValue(text, JSON_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
|
||||||
return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,7 +145,7 @@ public class JsonUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
OBJECT_MAPPER.readTree(str);
|
JSON_MAPPER.readTree(str);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -197,7 +163,7 @@ public class JsonUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
JsonNode node = OBJECT_MAPPER.readTree(str);
|
JsonNode node = JSON_MAPPER.readTree(str);
|
||||||
return node.isObject();
|
return node.isObject();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -215,7 +181,7 @@ public class JsonUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
JsonNode node = OBJECT_MAPPER.readTree(str);
|
JsonNode node = JSON_MAPPER.readTree(str);
|
||||||
return node.isArray();
|
return node.isArray();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -29,12 +29,12 @@
|
|||||||
<!-- dynamic-datasource 多数据源-->
|
<!-- dynamic-datasource 多数据源-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
<artifactId>dynamic-datasource-spring-boot4-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
<artifactId>mybatis-plus-spring-boot4-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -28,6 +28,12 @@
|
|||||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redisson</groupId>
|
||||||
|
<artifactId>redisson-spring-cache</artifactId>
|
||||||
|
<version>${redisson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
|
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
|
|||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||||
@@ -47,7 +48,7 @@ public class RedisConfig {
|
|||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
|
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
|
||||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
|
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
|
||||||
ObjectMapper om = new ObjectMapper();
|
JsonMapper om = new JsonMapper();
|
||||||
om.registerModule(javaTimeModule);
|
om.registerModule(javaTimeModule);
|
||||||
om.setTimeZone(TimeZone.getDefault());
|
om.setTimeZone(TimeZone.getDefault());
|
||||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
@@ -64,6 +65,8 @@ public class RedisConfig {
|
|||||||
.setNettyThreads(redissonProperties.getNettyThreads())
|
.setNettyThreads(redissonProperties.getNettyThreads())
|
||||||
// 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现)
|
// 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现)
|
||||||
.setUseScriptCache(true)
|
.setUseScriptCache(true)
|
||||||
|
//设置redis key前缀
|
||||||
|
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
|
||||||
.setCodec(codec);
|
.setCodec(codec);
|
||||||
if (SpringUtils.isVirtual()) {
|
if (SpringUtils.isVirtual()) {
|
||||||
config.setNettyExecutor(new VirtualThreadTaskExecutor("redisson-"));
|
config.setNettyExecutor(new VirtualThreadTaskExecutor("redisson-"));
|
||||||
@@ -72,8 +75,6 @@ public class RedisConfig {
|
|||||||
if (ObjectUtil.isNotNull(singleServerConfig)) {
|
if (ObjectUtil.isNotNull(singleServerConfig)) {
|
||||||
// 使用单机模式
|
// 使用单机模式
|
||||||
config.useSingleServer()
|
config.useSingleServer()
|
||||||
//设置redis key前缀
|
|
||||||
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
|
|
||||||
.setTimeout(singleServerConfig.getTimeout())
|
.setTimeout(singleServerConfig.getTimeout())
|
||||||
.setClientName(singleServerConfig.getClientName())
|
.setClientName(singleServerConfig.getClientName())
|
||||||
.setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
|
.setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
|
||||||
@@ -85,8 +86,6 @@ public class RedisConfig {
|
|||||||
RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
|
RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
|
||||||
if (ObjectUtil.isNotNull(clusterServersConfig)) {
|
if (ObjectUtil.isNotNull(clusterServersConfig)) {
|
||||||
config.useClusterServers()
|
config.useClusterServers()
|
||||||
//设置redis key前缀
|
|
||||||
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
|
|
||||||
.setTimeout(clusterServersConfig.getTimeout())
|
.setTimeout(clusterServersConfig.getTimeout())
|
||||||
.setClientName(clusterServersConfig.getClientName())
|
.setClientName(clusterServersConfig.getClientName())
|
||||||
.setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
|
.setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.dromara.common.redis.handler;
|
package org.dromara.common.redis.handler;
|
||||||
|
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.redisson.api.NameMapper;
|
import org.redisson.config.NameMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* redis缓存key前缀处理
|
* redis缓存key前缀处理
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.dromara.common.redis.manager;
|
|||||||
import org.dromara.common.redis.utils.RedisUtils;
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
import org.redisson.api.RMap;
|
import org.redisson.api.RMap;
|
||||||
import org.redisson.api.RMapCache;
|
import org.redisson.api.RMapCache;
|
||||||
|
import org.redisson.api.map.event.MapEntryListener;
|
||||||
import org.redisson.spring.cache.CacheConfig;
|
import org.redisson.spring.cache.CacheConfig;
|
||||||
import org.redisson.spring.cache.RedissonCache;
|
import org.redisson.spring.cache.RedissonCache;
|
||||||
import org.springframework.boot.convert.DurationStyle;
|
import org.springframework.boot.convert.DurationStyle;
|
||||||
@@ -189,6 +190,9 @@ public class PlusSpringCacheManager implements CacheManager {
|
|||||||
cache = oldCache;
|
cache = oldCache;
|
||||||
} else {
|
} else {
|
||||||
map.setMaxSize(config.getMaxSize());
|
map.setMaxSize(config.getMaxSize());
|
||||||
|
for (MapEntryListener listener : config.getListeners()) {
|
||||||
|
map.addListener(listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.dromara.common.sensitive.annotation;
|
package org.dromara.common.sensitive.annotation;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import org.dromara.common.sensitive.core.SensitiveStrategy;
|
import org.dromara.common.sensitive.core.SensitiveStrategy;
|
||||||
import org.dromara.common.sensitive.handler.SensitiveHandler;
|
import org.dromara.common.sensitive.handler.SensitiveHandler;
|
||||||
|
import tools.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@@ -20,6 +20,7 @@ import java.lang.annotation.Target;
|
|||||||
@JacksonAnnotationsInside
|
@JacksonAnnotationsInside
|
||||||
@JsonSerialize(using = SensitiveHandler.class)
|
@JsonSerialize(using = SensitiveHandler.class)
|
||||||
public @interface Sensitive {
|
public @interface Sensitive {
|
||||||
|
|
||||||
SensitiveStrategy strategy();
|
SensitiveStrategy strategy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
package org.dromara.common.sensitive.handler;
|
package org.dromara.common.sensitive.handler;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import com.fasterxml.jackson.databind.BeanProperty;
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
|
||||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
|
||||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.dromara.common.sensitive.annotation.Sensitive;
|
import org.dromara.common.sensitive.annotation.Sensitive;
|
||||||
import org.dromara.common.sensitive.core.SensitiveService;
|
import org.dromara.common.sensitive.core.SensitiveService;
|
||||||
import org.dromara.common.sensitive.core.SensitiveStrategy;
|
import org.dromara.common.sensitive.core.SensitiveStrategy;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
|
import tools.jackson.core.JacksonException;
|
||||||
|
import tools.jackson.core.JsonGenerator;
|
||||||
|
import tools.jackson.databind.BeanProperty;
|
||||||
|
import tools.jackson.databind.SerializationContext;
|
||||||
|
import tools.jackson.databind.ValueSerializer;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,14 +21,14 @@ import java.util.Objects;
|
|||||||
* @author Yjoioooo
|
* @author Yjoioooo
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SensitiveHandler extends JsonSerializer<String> implements ContextualSerializer {
|
public class SensitiveHandler extends ValueSerializer<String> {
|
||||||
|
|
||||||
private SensitiveStrategy strategy;
|
private SensitiveStrategy strategy;
|
||||||
private String[] roleKey;
|
private String[] roleKey;
|
||||||
private String[] perms;
|
private String[] perms;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
public void serialize(String value, JsonGenerator gen, SerializationContext ctxt) throws JacksonException {
|
||||||
try {
|
try {
|
||||||
SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
|
SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
|
||||||
if (ObjectUtil.isNotNull(sensitiveService) && sensitiveService.isSensitive(roleKey, perms)) {
|
if (ObjectUtil.isNotNull(sensitiveService) && sensitiveService.isSensitive(roleKey, perms)) {
|
||||||
@@ -45,7 +43,7 @@ public class SensitiveHandler extends JsonSerializer<String> implements Contextu
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
|
public ValueSerializer<?> createContextual(SerializationContext ctxt, BeanProperty property) {
|
||||||
Sensitive annotation = property.getAnnotation(Sensitive.class);
|
Sensitive annotation = property.getAnnotation(Sensitive.class);
|
||||||
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
|
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
|
||||||
this.strategy = annotation.strategy();
|
this.strategy = annotation.strategy();
|
||||||
@@ -53,6 +51,6 @@ public class SensitiveHandler extends JsonSerializer<String> implements Contextu
|
|||||||
this.perms = annotation.perms();
|
this.perms = annotation.perms();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return prov.findValueSerializer(property.getType(), property);
|
return super.createContextual(ctxt, property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import org.dromara.common.sms.core.dao.PlusSmsDao;
|
|||||||
import org.dromara.common.sms.handler.SmsExceptionHandler;
|
import org.dromara.common.sms.handler.SmsExceptionHandler;
|
||||||
import org.dromara.sms4j.api.dao.SmsDao;
|
import org.dromara.sms4j.api.dao.SmsDao;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
import org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ import org.springframework.context.annotation.Primary;
|
|||||||
*
|
*
|
||||||
* @author Feng
|
* @author Feng
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration(after = {RedisAutoConfiguration.class})
|
@AutoConfiguration(after = {DataRedisAutoConfiguration.class})
|
||||||
public class SmsAutoConfiguration {
|
public class SmsAutoConfiguration {
|
||||||
|
|
||||||
@Primary
|
@Primary
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package org.dromara.common.tenant.config;
|
package org.dromara.common.tenant.config;
|
||||||
|
|
||||||
import cn.dev33.satoken.dao.SaTokenDao;
|
import cn.dev33.satoken.dao.SaTokenDao;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
|
||||||
import org.dromara.common.redis.config.RedisConfig;
|
import org.dromara.common.redis.config.RedisConfig;
|
||||||
import org.dromara.common.redis.config.properties.RedissonProperties;
|
import org.dromara.common.redis.config.properties.RedissonProperties;
|
||||||
import org.dromara.common.tenant.core.TenantSaTokenDao;
|
import org.dromara.common.tenant.core.TenantSaTokenDao;
|
||||||
@@ -11,8 +9,6 @@ import org.dromara.common.tenant.handle.PlusTenantLineHandler;
|
|||||||
import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
|
import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
|
||||||
import org.dromara.common.tenant.manager.TenantSpringCacheManager;
|
import org.dromara.common.tenant.manager.TenantSpringCacheManager;
|
||||||
import org.dromara.common.tenant.properties.TenantProperties;
|
import org.dromara.common.tenant.properties.TenantProperties;
|
||||||
import org.redisson.config.ClusterServersConfig;
|
|
||||||
import org.redisson.config.SingleServerConfig;
|
|
||||||
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
@@ -49,19 +45,8 @@ public class TenantConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
|
public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
|
||||||
return config -> {
|
return config -> {
|
||||||
TenantKeyPrefixHandler nameMapper = new TenantKeyPrefixHandler(redissonProperties.getKeyPrefix());
|
// 设置多租户 redis key前缀
|
||||||
SingleServerConfig singleServerConfig = ReflectUtils.invokeGetter(config, "singleServerConfig");
|
config.setNameMapper(new TenantKeyPrefixHandler(redissonProperties.getKeyPrefix()));
|
||||||
if (ObjectUtil.isNotNull(singleServerConfig)) {
|
|
||||||
// 使用单机模式
|
|
||||||
// 设置多租户 redis key前缀
|
|
||||||
singleServerConfig.setNameMapper(nameMapper);
|
|
||||||
}
|
|
||||||
ClusterServersConfig clusterServersConfig = ReflectUtils.invokeGetter(config, "clusterServersConfig");
|
|
||||||
// 集群配置方式 参考下方注释
|
|
||||||
if (ObjectUtil.isNotNull(clusterServersConfig)) {
|
|
||||||
// 设置多租户 redis key前缀
|
|
||||||
clusterServersConfig.setNameMapper(nameMapper);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.dromara.common.translation.annotation;
|
package org.dromara.common.translation.annotation;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import org.dromara.common.translation.core.handler.TranslationHandler;
|
import org.dromara.common.translation.core.handler.TranslationHandler;
|
||||||
|
import tools.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@@ -11,10 +11,8 @@ import java.lang.annotation.*;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Inherited
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||||
@Documented
|
|
||||||
@JacksonAnnotationsInside
|
@JacksonAnnotationsInside
|
||||||
@JsonSerialize(using = TranslationHandler.class)
|
@JsonSerialize(using = TranslationHandler.class)
|
||||||
public @interface Translation {
|
public @interface Translation {
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
package org.dromara.common.translation.config;
|
package org.dromara.common.translation.config;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.translation.annotation.TranslationType;
|
import org.dromara.common.translation.annotation.TranslationType;
|
||||||
import org.dromara.common.translation.core.TranslationInterface;
|
import org.dromara.common.translation.core.TranslationInterface;
|
||||||
import org.dromara.common.translation.core.handler.TranslationBeanSerializerModifier;
|
import org.dromara.common.translation.core.handler.TranslationBeanSerializerModifier;
|
||||||
import org.dromara.common.translation.core.handler.TranslationHandler;
|
import org.dromara.common.translation.core.handler.TranslationHandler;
|
||||||
import jakarta.annotation.PostConstruct;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
|
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import tools.jackson.databind.ser.SerializerFactory;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -26,9 +28,6 @@ public class TranslationConfig {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private List<TranslationInterface<?>> list;
|
private List<TranslationInterface<?>> list;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
Map<String, TranslationInterface<?>> map = new HashMap<>(list.size());
|
Map<String, TranslationInterface<?>> map = new HashMap<>(list.size());
|
||||||
@@ -41,10 +40,15 @@ public class TranslationConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TranslationHandler.TRANSLATION_MAPPER.putAll(map);
|
TranslationHandler.TRANSLATION_MAPPER.putAll(map);
|
||||||
// 设置 Bean 序列化修改器
|
}
|
||||||
objectMapper.setSerializerFactory(
|
|
||||||
objectMapper.getSerializerFactory()
|
@Bean
|
||||||
.withSerializerModifier(new TranslationBeanSerializerModifier()));
|
public JsonMapperBuilderCustomizer translationInitCustomizer() {
|
||||||
|
return builder -> {
|
||||||
|
SerializerFactory serializerFactory = builder.serializerFactory();
|
||||||
|
serializerFactory = serializerFactory.withSerializerModifier(new TranslationBeanSerializerModifier());
|
||||||
|
builder.serializerFactory(serializerFactory);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.dromara.common.translation.core.handler;
|
package org.dromara.common.translation.core.handler;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.BeanDescription;
|
import tools.jackson.databind.BeanDescription;
|
||||||
import com.fasterxml.jackson.databind.SerializationConfig;
|
import tools.jackson.databind.SerializationConfig;
|
||||||
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
|
import tools.jackson.databind.ser.BeanPropertyWriter;
|
||||||
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
|
import tools.jackson.databind.ser.ValueSerializerModifier;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -12,10 +12,10 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
public class TranslationBeanSerializerModifier extends BeanSerializerModifier {
|
public class TranslationBeanSerializerModifier extends ValueSerializerModifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
|
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription.Supplier beanDesc,
|
||||||
List<BeanPropertyWriter> beanProperties) {
|
List<BeanPropertyWriter> beanProperties) {
|
||||||
for (BeanPropertyWriter writer : beanProperties) {
|
for (BeanPropertyWriter writer : beanProperties) {
|
||||||
// 如果序列化器为 TranslationHandler 的话 将 Null 值也交给他处理
|
// 如果序列化器为 TranslationHandler 的话 将 Null 值也交给他处理
|
||||||
@@ -23,7 +23,7 @@ public class TranslationBeanSerializerModifier extends BeanSerializerModifier {
|
|||||||
writer.assignNullSerializer(serializer);
|
writer.assignNullSerializer(serializer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return beanProperties;
|
return super.changeProperties(config, beanDesc, beanProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
package org.dromara.common.translation.core.handler;
|
package org.dromara.common.translation.core.handler;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import com.fasterxml.jackson.databind.BeanProperty;
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
|
||||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
|
||||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||||
import org.dromara.common.translation.annotation.Translation;
|
import org.dromara.common.translation.annotation.Translation;
|
||||||
import org.dromara.common.translation.core.TranslationInterface;
|
import org.dromara.common.translation.core.TranslationInterface;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import tools.jackson.core.JacksonException;
|
||||||
|
import tools.jackson.core.JsonGenerator;
|
||||||
|
import tools.jackson.databind.BeanProperty;
|
||||||
|
import tools.jackson.databind.SerializationContext;
|
||||||
|
import tools.jackson.databind.ValueSerializer;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -24,7 +22,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TranslationHandler extends JsonSerializer<Object> implements ContextualSerializer {
|
public class TranslationHandler extends ValueSerializer<Object> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局翻译实现类映射器
|
* 全局翻译实现类映射器
|
||||||
@@ -34,7 +32,7 @@ public class TranslationHandler extends JsonSerializer<Object> implements Contex
|
|||||||
private Translation translation;
|
private Translation translation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
public void serialize(Object value, JsonGenerator gen, SerializationContext ctxt) throws JacksonException {
|
||||||
TranslationInterface<?> trans = TRANSLATION_MAPPER.get(translation.type());
|
TranslationInterface<?> trans = TRANSLATION_MAPPER.get(translation.type());
|
||||||
if (ObjectUtil.isNotNull(trans)) {
|
if (ObjectUtil.isNotNull(trans)) {
|
||||||
// 如果映射字段不为空 则取映射字段的值
|
// 如果映射字段不为空 则取映射字段的值
|
||||||
@@ -48,24 +46,24 @@ public class TranslationHandler extends JsonSerializer<Object> implements Contex
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Object result = trans.translation(value, translation.other());
|
Object result = trans.translation(value, translation.other());
|
||||||
gen.writeObject(result);
|
gen.writePOJO(result);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("翻译处理异常,type: {}, value: {}", translation.type(), value, e);
|
log.error("翻译处理异常,type: {}, value: {}", translation.type(), value, e);
|
||||||
// 出现异常时输出原始值而不是中断序列化
|
// 出现异常时输出原始值而不是中断序列化
|
||||||
gen.writeObject(value);
|
gen.writePOJO(value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gen.writeObject(value);
|
gen.writePOJO(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
|
public ValueSerializer<?> createContextual(SerializationContext ctxt, BeanProperty property) {
|
||||||
Translation translation = property.getAnnotation(Translation.class);
|
Translation translation = property.getAnnotation(Translation.class);
|
||||||
if (Objects.nonNull(translation)) {
|
if (Objects.nonNull(translation)) {
|
||||||
this.translation = translation;
|
this.translation = translation;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return prov.findValueSerializer(property.getType(), property);
|
return super.createContextual(ctxt, property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<!-- web 容器使用 undertow 性能更强 -->
|
<!-- web 容器使用 undertow 性能更强 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package org.dromara.common.web.config;
|
|||||||
|
|
||||||
import org.dromara.common.web.core.I18nLocaleResolver;
|
import org.dromara.common.web.core.I18nLocaleResolver;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.web.servlet.LocaleResolver;
|
import org.springframework.web.servlet.LocaleResolver;
|
||||||
|
|
||||||
|
|||||||
@@ -1,63 +1,63 @@
|
|||||||
package org.dromara.common.web.config;
|
//package org.dromara.common.web.config;
|
||||||
|
//
|
||||||
import io.undertow.server.DefaultByteBufferPool;
|
//import io.undertow.server.DefaultByteBufferPool;
|
||||||
import io.undertow.server.handlers.DisallowedMethodsHandler;
|
//import io.undertow.server.handlers.DisallowedMethodsHandler;
|
||||||
import io.undertow.util.HttpString;
|
//import io.undertow.util.HttpString;
|
||||||
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
|
//import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
//import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
//import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
//import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
//import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
//import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* Undertow 自定义配置
|
// * Undertow 自定义配置
|
||||||
*
|
// *
|
||||||
* @author Lion Li
|
// * @author Lion Li
|
||||||
*/
|
// */
|
||||||
@AutoConfiguration
|
//@AutoConfiguration
|
||||||
public class UndertowConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
|
//public class UndertowConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* 自定义 Undertow 配置
|
// * 自定义 Undertow 配置
|
||||||
* <p>
|
// * <p>
|
||||||
* 主要配置内容包括:
|
// * 主要配置内容包括:
|
||||||
* 1. 配置 WebSocket 部署信息
|
// * 1. 配置 WebSocket 部署信息
|
||||||
* 2. 在虚拟线程模式下使用虚拟线程池
|
// * 2. 在虚拟线程模式下使用虚拟线程池
|
||||||
* 3. 禁用不安全的 HTTP 方法,如 CONNECT、TRACE、TRACK
|
// * 3. 禁用不安全的 HTTP 方法,如 CONNECT、TRACE、TRACK
|
||||||
* </p>
|
// * </p>
|
||||||
*
|
// *
|
||||||
* @param factory Undertow 的 Web 服务器工厂
|
// * @param factory Undertow 的 Web 服务器工厂
|
||||||
*/
|
// */
|
||||||
@Override
|
// @Override
|
||||||
public void customize(UndertowServletWebServerFactory factory) {
|
// public void customize(UndertowServletWebServerFactory factory) {
|
||||||
factory.addDeploymentInfoCustomizers(deploymentInfo -> {
|
// factory.addDeploymentInfoCustomizers(deploymentInfo -> {
|
||||||
// 配置 WebSocket 部署信息,设置 WebSocket 使用的缓冲区池
|
// // 配置 WebSocket 部署信息,设置 WebSocket 使用的缓冲区池
|
||||||
WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
|
// WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
|
||||||
webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(true, 1024));
|
// webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(true, 1024));
|
||||||
deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
|
// deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
|
||||||
|
//
|
||||||
// 如果启用了虚拟线程,配置 Undertow 使用虚拟线程池
|
// // 如果启用了虚拟线程,配置 Undertow 使用虚拟线程池
|
||||||
if (SpringUtils.isVirtual()) {
|
// if (SpringUtils.isVirtual()) {
|
||||||
// 创建虚拟线程池,线程池前缀为 "undertow-"
|
// // 创建虚拟线程池,线程池前缀为 "undertow-"
|
||||||
VirtualThreadTaskExecutor executor = new VirtualThreadTaskExecutor("undertow-");
|
// VirtualThreadTaskExecutor executor = new VirtualThreadTaskExecutor("undertow-");
|
||||||
// 设置虚拟线程池为执行器和异步执行器
|
// // 设置虚拟线程池为执行器和异步执行器
|
||||||
deploymentInfo.setExecutor(executor);
|
// deploymentInfo.setExecutor(executor);
|
||||||
deploymentInfo.setAsyncExecutor(executor);
|
// deploymentInfo.setAsyncExecutor(executor);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 配置禁止某些不安全的 HTTP 方法(如 CONNECT、TRACE、TRACK)
|
// // 配置禁止某些不安全的 HTTP 方法(如 CONNECT、TRACE、TRACK)
|
||||||
deploymentInfo.addInitialHandlerChainWrapper(handler -> {
|
// deploymentInfo.addInitialHandlerChainWrapper(handler -> {
|
||||||
// 禁止三个方法 CONNECT/TRACE/TRACK 也是不安全的 避免爬虫骚扰
|
// // 禁止三个方法 CONNECT/TRACE/TRACK 也是不安全的 避免爬虫骚扰
|
||||||
HttpString[] disallowedHttpMethods = {
|
// HttpString[] disallowedHttpMethods = {
|
||||||
HttpString.tryFromString("CONNECT"),
|
// HttpString.tryFromString("CONNECT"),
|
||||||
HttpString.tryFromString("TRACE"),
|
// HttpString.tryFromString("TRACE"),
|
||||||
HttpString.tryFromString("TRACK")
|
// HttpString.tryFromString("TRACK")
|
||||||
};
|
// };
|
||||||
// 使用 DisallowedMethodsHandler 拦截并拒绝这些方法的请求
|
// // 使用 DisallowedMethodsHandler 拦截并拒绝这些方法的请求
|
||||||
return new DisallowedMethodsHandler(handler, disallowedHttpMethods);
|
// return new DisallowedMethodsHandler(handler, disallowedHttpMethods);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.dromara.common.web.handler;
|
|||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.http.HttpStatus;
|
import cn.hutool.http.HttpStatus;
|
||||||
import com.fasterxml.jackson.core.JsonParseException;
|
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.validation.ConstraintViolation;
|
import jakarta.validation.ConstraintViolation;
|
||||||
@@ -14,6 +13,7 @@ import org.dromara.common.core.exception.SseException;
|
|||||||
import org.dromara.common.core.exception.base.BaseException;
|
import org.dromara.common.core.exception.base.BaseException;
|
||||||
import org.dromara.common.core.utils.StreamUtils;
|
import org.dromara.common.core.utils.StreamUtils;
|
||||||
import org.dromara.common.json.utils.JsonUtils;
|
import org.dromara.common.json.utils.JsonUtils;
|
||||||
|
import org.springframework.boot.json.JsonParseException;
|
||||||
import org.springframework.context.MessageSourceResolvable;
|
import org.springframework.context.MessageSourceResolvable;
|
||||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||||
import org.springframework.expression.ExpressionException;
|
import org.springframework.expression.ExpressionException;
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ import cn.hutool.core.io.IoUtil;
|
|||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -19,6 +15,10 @@ import org.dromara.common.web.filter.RepeatedlyRequestWrapper;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import tools.jackson.databind.JsonNode;
|
||||||
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
|
import tools.jackson.databind.node.ArrayNode;
|
||||||
|
import tools.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -45,8 +45,8 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
|
|||||||
if (request instanceof RepeatedlyRequestWrapper) {
|
if (request instanceof RepeatedlyRequestWrapper) {
|
||||||
jsonParam = IoUtil.read(request.getReader());
|
jsonParam = IoUtil.read(request.getReader());
|
||||||
if (StringUtils.isNotBlank(jsonParam)) {
|
if (StringUtils.isNotBlank(jsonParam)) {
|
||||||
ObjectMapper objectMapper = JsonUtils.getObjectMapper();
|
JsonMapper jsonMapper = JsonUtils.getJsonMapper();
|
||||||
JsonNode rootNode = objectMapper.readTree(jsonParam);
|
JsonNode rootNode = jsonMapper.readTree(jsonParam);
|
||||||
removeSensitiveFields(rootNode, SystemConstants.EXCLUDE_PROPERTIES);
|
removeSensitiveFields(rootNode, SystemConstants.EXCLUDE_PROPERTIES);
|
||||||
jsonParam = rootNode.toString();
|
jsonParam = rootNode.toString();
|
||||||
}
|
}
|
||||||
@@ -79,14 +79,14 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
|
|||||||
ObjectNode objectNode = (ObjectNode) node;
|
ObjectNode objectNode = (ObjectNode) node;
|
||||||
// 收集要删除的字段名(避免 ConcurrentModification)
|
// 收集要删除的字段名(避免 ConcurrentModification)
|
||||||
Set<String> fieldsToRemove = new HashSet<>();
|
Set<String> fieldsToRemove = new HashSet<>();
|
||||||
objectNode.fieldNames().forEachRemaining(fieldName -> {
|
objectNode.propertyNames().forEach(fieldName -> {
|
||||||
if (ArrayUtil.contains(excludeProperties, fieldName)) {
|
if (ArrayUtil.contains(excludeProperties, fieldName)) {
|
||||||
fieldsToRemove.add(fieldName);
|
fieldsToRemove.add(fieldName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
fieldsToRemove.forEach(objectNode::remove);
|
fieldsToRemove.forEach(objectNode::remove);
|
||||||
// 递归处理子节点
|
// 递归处理子节点
|
||||||
objectNode.elements().forEachRemaining(child -> removeSensitiveFields(child, excludeProperties));
|
objectNode.values().forEach(child -> removeSensitiveFields(child, excludeProperties));
|
||||||
} else if (node.isArray()) {
|
} else if (node.isArray()) {
|
||||||
ArrayNode arrayNode = (ArrayNode) node;
|
ArrayNode arrayNode = (ArrayNode) node;
|
||||||
for (JsonNode child : arrayNode) {
|
for (JsonNode child : arrayNode) {
|
||||||
|
|||||||
@@ -2,4 +2,3 @@ org.dromara.common.web.config.CaptchaConfig
|
|||||||
org.dromara.common.web.config.FilterConfig
|
org.dromara.common.web.config.FilterConfig
|
||||||
org.dromara.common.web.config.I18nConfig
|
org.dromara.common.web.config.I18nConfig
|
||||||
org.dromara.common.web.config.ResourcesConfig
|
org.dromara.common.web.config.ResourcesConfig
|
||||||
org.dromara.common.web.config.UndertowConfig
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<!-- web 容器使用 undertow 性能更强 -->
|
<!-- web 容器使用 undertow 性能更强 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- spring security 安全认证 -->
|
<!-- spring security 安全认证 -->
|
||||||
|
|||||||
@@ -1,146 +0,0 @@
|
|||||||
package com.aizuda.snailjob.server.common.register;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.aizuda.snailjob.common.core.enums.NodeTypeEnum;
|
|
||||||
import com.aizuda.snailjob.common.core.util.JsonUtil;
|
|
||||||
import com.aizuda.snailjob.common.core.util.NetUtil;
|
|
||||||
import com.aizuda.snailjob.common.core.util.SnailJobVersion;
|
|
||||||
import com.aizuda.snailjob.common.core.util.StreamUtils;
|
|
||||||
import com.aizuda.snailjob.common.log.SnailJobLog;
|
|
||||||
import com.aizuda.snailjob.server.common.cache.CacheConsumerGroup;
|
|
||||||
import com.aizuda.snailjob.server.common.config.SystemProperties;
|
|
||||||
import com.aizuda.snailjob.server.common.convert.RegisterNodeInfoConverter;
|
|
||||||
import com.aizuda.snailjob.server.common.dto.ServerNodeExtAttrs;
|
|
||||||
import com.aizuda.snailjob.server.common.handler.InstanceManager;
|
|
||||||
import com.aizuda.snailjob.template.datasource.persistence.po.ServerNode;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务端注册
|
|
||||||
*
|
|
||||||
* @author opensnail
|
|
||||||
* @date 2023-06-07
|
|
||||||
* @since 1.6.0
|
|
||||||
*/
|
|
||||||
@Component(ServerRegister.BEAN_NAME)
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class ServerRegister extends AbstractRegister {
|
|
||||||
public static final String BEAN_NAME = "serverRegister";
|
|
||||||
private final ScheduledExecutorService serverRegisterNode = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "server-register-node"));
|
|
||||||
public static final int DELAY_TIME = 30;
|
|
||||||
public static final String CURRENT_CID;
|
|
||||||
public static final String GROUP_NAME = "DEFAULT_SERVER";
|
|
||||||
public static final String NAMESPACE_ID = "DEFAULT_SERVER_NAMESPACE_ID";
|
|
||||||
private final InstanceManager instanceManager;
|
|
||||||
private final SystemProperties systemProperties;
|
|
||||||
private final ServerProperties serverProperties;
|
|
||||||
|
|
||||||
static {
|
|
||||||
CURRENT_CID = IdUtil.getSnowflakeNextIdStr();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supports(int type) {
|
|
||||||
return getNodeType().equals(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void beforeProcessor(RegisterContext context) {
|
|
||||||
// 新增扩展参数
|
|
||||||
ServerNodeExtAttrs serverNodeExtAttrs = new ServerNodeExtAttrs();
|
|
||||||
serverNodeExtAttrs.setWebPort(serverProperties.getPort());
|
|
||||||
serverNodeExtAttrs.setSystemVersion(SnailJobVersion.getVersion());
|
|
||||||
|
|
||||||
context.setGroupName(GROUP_NAME);
|
|
||||||
context.setHostId(CURRENT_CID);
|
|
||||||
String serverHost = systemProperties.getServerHost();
|
|
||||||
if (StrUtil.isEmptyIfStr(serverHost)) {
|
|
||||||
serverHost = NetUtil.getLocalIpStr();
|
|
||||||
}
|
|
||||||
context.setHostIp(serverHost);
|
|
||||||
context.setHostPort(systemProperties.getServerPort());
|
|
||||||
context.setContextPath(Optional.ofNullable(serverProperties.getServlet().getContextPath()).orElse(StrUtil.EMPTY));
|
|
||||||
context.setNamespaceId(NAMESPACE_ID);
|
|
||||||
context.setExtAttrs(JsonUtil.toJsonString(serverNodeExtAttrs));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected LocalDateTime getExpireAt() {
|
|
||||||
return LocalDateTime.now().plusSeconds(DELAY_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean doRegister(RegisterContext context, ServerNode serverNode) {
|
|
||||||
refreshExpireAt(Lists.newArrayList(serverNode));
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void afterProcessor(final ServerNode serverNode) {
|
|
||||||
try {
|
|
||||||
// 同步当前POD消费的组的节点信息
|
|
||||||
// netty的client只会注册到一个服务端,若组分配的和client连接的不是一个POD则会导致当前POD没有其他客户端的注册信息
|
|
||||||
ConcurrentMap<String /*groupName*/, Set<String>/*namespaceId*/> allConsumerGroupName = CacheConsumerGroup.getAllConsumerGroupName();
|
|
||||||
if (CollUtil.isNotEmpty(allConsumerGroupName)) {
|
|
||||||
Set<String> namespaceIdSets = StreamUtils.toSetByFlatMap(allConsumerGroupName.values(), Set::stream);
|
|
||||||
if (CollUtil.isEmpty(namespaceIdSets)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ServerNode> serverNodes = serverNodeMapper.selectList(
|
|
||||||
new LambdaQueryWrapper<ServerNode>()
|
|
||||||
.eq(ServerNode::getNodeType, NodeTypeEnum.CLIENT.getType())
|
|
||||||
.in(ServerNode::getNamespaceId, namespaceIdSets)
|
|
||||||
.in(ServerNode::getGroupName, allConsumerGroupName.keySet()));
|
|
||||||
for (final ServerNode node : serverNodes) {
|
|
||||||
// 刷新全量本地缓存
|
|
||||||
instanceManager.registerOrUpdate(RegisterNodeInfoConverter.INSTANCE.toRegisterNodeInfo(node));
|
|
||||||
// 刷新过期时间
|
|
||||||
CacheConsumerGroup.addOrUpdate(node.getGroupName(), node.getNamespaceId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
SnailJobLog.LOCAL.error("Client refresh failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Integer getNodeType() {
|
|
||||||
return NodeTypeEnum.SERVER.getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
SnailJobLog.LOCAL.info("ServerRegister start");
|
|
||||||
|
|
||||||
serverRegisterNode.scheduleAtFixedRate(() -> {
|
|
||||||
try {
|
|
||||||
this.register(new RegisterContext());
|
|
||||||
} catch (Exception e) {
|
|
||||||
SnailJobLog.LOCAL.error("Server-side registration failed", e);
|
|
||||||
}
|
|
||||||
}, 0, DELAY_TIME * 2 / 3, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
SnailJobLog.LOCAL.info("ServerRegister close");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user