27 Commits
dev ... v5.5.2

Author SHA1 Message Date
疯狂的狮子Li
b6eacfa5a8 !813 紧急修复Ip2Region InputStream读取函数导致的OOM问题
Merge pull request !813 from 疯狂的狮子Li/dev
2025-12-23 06:44:24 +00:00
疯狂的狮子Li
da4dffcfce !812 发布 5.5.2 版本 2025年最后一版
Merge pull request !812 from 疯狂的狮子Li/dev
2025-12-23 01:38:19 +00:00
疯狂的狮子Li
b58085fde1 !779 发布 5.5.1 正式版 日常依赖升级bug修复
Merge pull request !779 from 疯狂的狮子Li/dev
2025-10-28 03:21:27 +00:00
疯狂的狮子Li
b30ffa952f !766 发布 5.5.0 喜迎国庆
Merge pull request !766 from 疯狂的狮子Li/dev
2025-09-22 03:17:27 +00:00
疯狂的狮子Li
fd5d028e95 fix 修复 有某些无聊人士 对一个demo案例提漏洞 CVE-2025-6925
Signed-off-by: 疯狂的狮子Li <15040126243@163.com>
2025-07-04 01:10:49 +00:00
疯狂的狮子Li
64100cf1ff !712 发布 5.4.1 小步迭代修复问题
Merge pull request !712 from 疯狂的狮子Li/dev
2025-07-01 01:12:39 +00:00
疯狂的狮子Li
7e7d857ba5 Merge remote-tracking branch 'origin/dev' into 5.X 2025-05-29 18:18:20 +08:00
疯狂的狮子Li
d22b2a10df update 优化 PermissionService 无实现类也可以启动服务 2025-05-29 16:28:56 +08:00
疯狂的狮子Li
957a4d1fcd fix 修复 监听器 flowParams 为null报错问题 2025-05-29 16:28:56 +08:00
疯狂的狮子Li
49ef8378fe !691 发布 5.4.0 正式版
Merge pull request !691 from 疯狂的狮子Li/dev
2025-05-29 03:14:59 +00:00
疯狂的狮子Li
57dd6831d3 !664 发布 5.3.1 正式版
Merge pull request !664 from 疯狂的狮子Li/dev
2025-03-27 02:54:00 +00:00
疯狂的狮子Li
8aa60abb1f !663 回退 'Pull Request !662 : 发布 5.3.1 正式版'
* 回退 'Pull Request !662 : 发布 5.3.1 正式版'
2025-03-27 02:53:23 +00:00
疯狂的狮子Li
7a9f51fc7a !662 发布 5.3.1 正式版
* 🐳发布 5.3.1 正式版
* update 优化 删除无用配置
* fix 修复 excel模板导出数据被覆盖的问题
* update 优化 统一用户密码校验长度
* update mybatis-plus 3.5.10.1 => 3.5.11
* fix 修复 跨域未设置请求头问题(cloud版本不需要 vue版本需要)
2025-03-27 02:51:57 +00:00
疯狂的狮子Li
159e30c982 !661 发布 5.3.1-BETA2 公测版本
Merge pull request !661 from 疯狂的狮子Li/dev
2025-03-21 07:25:25 +00:00
疯狂的狮子Li
7334d91d6b !652 发布 5.3.1-BETA 公测版本
Merge pull request !652 from 疯狂的狮子Li/dev
2025-03-13 05:27:36 +00:00
疯狂的狮子Li
95c01301f6 !644 同步修复一些问题
Merge pull request !644 from 疯狂的狮子Li/dev
2025-02-07 06:19:28 +00:00
疯狂的狮子Li
296466fa13 !640 发布 5.3.0 新春版 祝大家新年快乐
Merge pull request !640 from 疯狂的狮子Li/dev
2025-01-24 05:08:28 +00:00
疯狂的狮子Li
3c8d864b5f !639 发布 5.3.0-BETA 公测版本
Merge pull request !639 from 疯狂的狮子Li/dev
2025-01-20 03:35:45 +00:00
疯狂的狮子Li
ea50a57602 update 优化 xss包装器 Parameter 处理 兼容某些容器不允许改参数的情况 2024-11-21 10:17:34 +08:00
疯狂的狮子Li
7e14b98676 reset 回滚错误修改
Signed-off-by: 疯狂的狮子Li <15040126243@163.com>
2024-10-28 09:46:28 +00:00
疯狂的狮子Li
015b406001 !591 发布 5.2.3 正式版
Merge pull request !591 from 疯狂的狮子Li/dev
2024-10-25 03:09:23 +00:00
疯狂的狮子Li
098d3347a0 !577 发布 5.2.2 正式版 安全性提升
Merge pull request !577 from 疯狂的狮子Li/dev
2024-08-26 03:43:59 +00:00
疯狂的狮子Li
08d4493994 update 优化 bug 模板 2024-07-15 15:19:22 +08:00
疯狂的狮子Li
367d739e2d Merge remote-tracking branch 'origin/5.X' into 5.X 2024-07-09 16:38:43 +08:00
疯狂的狮子Li
d6688a367d !562 ♥️发布 5.2.1 正式版本
Merge pull request !562 from 疯狂的狮子Li/dev
2024-07-09 02:42:40 +00:00
疯狂的狮子Li
0b331796e2 !551 ♥️发布 5.2.0 正式版本
Merge pull request !551 from 疯狂的狮子Li/dev
2024-06-20 02:10:15 +00:00
疯狂的狮子Li
456620b638 !549 ♥️发布 5.2.0-BETA2 公测版本
Merge pull request !549 from 疯狂的狮子Li/dev
2024-06-06 03:13:46 +00:00
6 changed files with 22 additions and 31 deletions

View File

@@ -38,7 +38,7 @@
<bouncycastle.version>1.80</bouncycastle.version> <bouncycastle.version>1.80</bouncycastle.version>
<justauth.version>1.16.7</justauth.version> <justauth.version>1.16.7</justauth.version>
<!-- 离线IP地址定位库 --> <!-- 离线IP地址定位库 -->
<ip2region.version>3.3.2</ip2region.version> <ip2region.version>3.3.1</ip2region.version>
<!-- OSS 配置 --> <!-- OSS 配置 -->
<aws.sdk.version>2.28.22</aws.sdk.version> <aws.sdk.version>2.28.22</aws.sdk.version>
<!-- SMS 配置 --> <!-- SMS 配置 -->

View File

@@ -1,5 +1,6 @@
package org.dromara.common.core.utils.ip; package org.dromara.common.core.utils.ip;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
@@ -8,6 +9,7 @@ import org.lionsoul.ip2region.service.Config;
import org.lionsoul.ip2region.service.Ip2Region; import org.lionsoul.ip2region.service.Ip2Region;
import org.lionsoul.ip2region.xdb.Util; import org.lionsoul.ip2region.xdb.Util;
import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.time.Duration; import java.time.Duration;
@@ -29,11 +31,6 @@ public class RegionUtils {
// 下载地址https://gitee.com/lionsoul/ip2region/blob/master/data/ip2region_v6.xdb // 下载地址https://gitee.com/lionsoul/ip2region/blob/master/data/ip2region_v6.xdb
public static final String DEFAULT_IPV6_XDB_PATH = "ip2region_v6.xdb"; public static final String DEFAULT_IPV6_XDB_PATH = "ip2region_v6.xdb";
// 默认缓存切片大小为15MB仅针对BufferCache全量读取有效如果你的xdb数据库很大合理设置该值可以有效提升BufferCache模式下的查询效率具体可以查看Ip2Region的README
// 注意设置过大的值可能会申请内存时因内存不足而导致OOM请合理设置该值。
// READMEhttps://gitee.com/lionsoul/ip2region/tree/master/binding/java
public static final int DEFAULT_CACHE_SLICE_BYTES = 1024 * 1024 * 15;
// 未知地址 // 未知地址
public static final String UNKNOWN_ADDRESS = "未知"; public static final String UNKNOWN_ADDRESS = "未知";
@@ -46,18 +43,20 @@ public class RegionUtils {
// 注意Ip2Region 的xdb文件加载策略 CachePolicy 有三种分别是BufferCache全量读取xdb到内存中、VIndexCache默认策略按需读取并缓存、NoCache实时读取 // 注意Ip2Region 的xdb文件加载策略 CachePolicy 有三种分别是BufferCache全量读取xdb到内存中、VIndexCache默认策略按需读取并缓存、NoCache实时读取
// 本项目工具使用的 CachePolicy 为 BufferCacheBufferCache会加载整个xdb文件到内存中setXdbInputStream 仅支持 BufferCache 策略。 // 本项目工具使用的 CachePolicy 为 BufferCacheBufferCache会加载整个xdb文件到内存中setXdbInputStream 仅支持 BufferCache 策略。
// 因为加载整个xdb文件会耗费非常大的内存如果你不希望加载整个xdb到内存中更推荐使用 VIndexCache 或 NoCache即实时读取文件策略和 setXdbPath/setXdbFile 加载方法需要注意的一点setXdbPath 和 setXdbFile 不支持读取ClassPath即源码和resource目录中的文件 // 因为加载整个xdb文件会耗费非常大的内存如果你不希望加载整个xdb到内存中更推荐使用 VIndexCache 或 NoCache即实时读取文件策略和 setXdbPath/setXdbFile 加载方法需要注意的一点setXdbPath 和 setXdbFile 不支持读取ClassPath即源码和resource目录中的文件
// 一般而言更建议把xdb数据库放到一个指定的文件目录中即不打包进jar包中然后使用 VIndexCache + 配合SearcherPool的并发池读取数据更方便随时更新xdb数据库 // 一般而言更建议把xdb数据库放到一个指定的文件目录中即不打包进jar包中然后使用 NoCache + 配合SearcherPool的并发池读取数据更方便随时更新xdb数据库
InputStream v4InputStream = ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH); // TODO 2025年12月23日 Ip2Region封装的 InputStream 读取函数 Searcher.loadContentFromInputStream 在Linux环境下会申请过大的byte[]空间而导致OOM这里先用临时文件的方案解决等后续 Ip2Region 更新解决方案
// 创建临时文件
File v4TempXdb = FileUtil.writeFromStream(ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH), FileUtil.createTempFile());
// IPv4配置 // IPv4配置
Config v4Config = Config.custom() Config v4Config = Config.custom()
.setCachePolicy(Config.BufferCache) .setCachePolicy(Config.BufferCache)
//.setXdbFile(v4TempXdb) .setXdbFile(v4TempXdb)
.setXdbInputStream(v4InputStream) // .setXdbInputStream(ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH))
//
.setCacheSliceBytes(DEFAULT_CACHE_SLICE_BYTES)
.asV4(); .asV4();
// 删除临时文件
v4TempXdb.delete();
// IPv6配置 // IPv6配置
Config v6Config = null; Config v6Config = null;
@@ -65,12 +64,17 @@ public class RegionUtils {
if (v6XdbInputStream == null) { if (v6XdbInputStream == null) {
log.warn("未加载 IPv6 地址库:未在类路径下找到文件 {}。当前仅启用 IPv4 查询。如需启用 IPv6请将 ip2region_v6.xdb 放置到 resources 目录", DEFAULT_IPV6_XDB_PATH); log.warn("未加载 IPv6 地址库:未在类路径下找到文件 {}。当前仅启用 IPv4 查询。如需启用 IPv6请将 ip2region_v6.xdb 放置到 resources 目录", DEFAULT_IPV6_XDB_PATH);
} else { } else {
// 创建临时文件
File v6TempXdb = FileUtil.writeFromStream(ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH), FileUtil.createTempFile());
v6Config = Config.custom() v6Config = Config.custom()
.setCachePolicy(Config.BufferCache) .setCachePolicy(Config.BufferCache)
//.setXdbFile(v6TempXdb) .setXdbFile(v6TempXdb)
.setXdbInputStream(v6XdbInputStream) // .setXdbInputStream(v6XdbInputStream)
.setCacheSliceBytes(DEFAULT_CACHE_SLICE_BYTES)
.asV6(); .asV6();
// 删除临时文件
v6TempXdb.delete();
} }
// 初始化Ip2Region实例 // 初始化Ip2Region实例

View File

@@ -14,7 +14,6 @@ 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.context.MessageSourceResolvable;
import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.expression.ExpressionException; import org.springframework.expression.ExpressionException;
import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotReadableException;
@@ -26,7 +25,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException; import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.method.annotation.HandlerMethodValidationException;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.servlet.NoHandlerFoundException;
@@ -193,16 +191,6 @@ public class GlobalExceptionHandler {
return R.fail(message); return R.fail(message);
} }
/**
* 方法参数校验异常 用于处理 @Validated 注解
*/
@ExceptionHandler(HandlerMethodValidationException.class)
public R<Void> handlerMethodValidationException(HandlerMethodValidationException e) {
log.error(e.getMessage());
String message = StreamUtils.join(e.getAllErrors(), MessageSourceResolvable::getDefaultMessage, ", ");
return R.fail(message);
}
/** /**
* JSON 解析异常Jackson 在处理 JSON 格式出错时抛出) * JSON 解析异常Jackson 在处理 JSON 格式出错时抛出)
* 可能是请求体格式非法,也可能是服务端反序列化失败 * 可能是请求体格式非法,也可能是服务端反序列化失败

View File

@@ -8,7 +8,6 @@ import org.dromara.common.websocket.holder.WebSocketSessionHolder;
import org.dromara.common.websocket.utils.WebSocketUtils; import org.dromara.common.websocket.utils.WebSocketUtils;
import org.springframework.web.socket.*; import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.AbstractWebSocketHandler; import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@@ -34,7 +33,7 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
log.info("[connect] invalid token received. sessionId: {}", session.getId()); log.info("[connect] invalid token received. sessionId: {}", session.getId());
return; return;
} }
WebSocketSessionHolder.addSession(loginUser.getUserId(), new ConcurrentWebSocketSessionDecorator(session, 10 * 1000, 64000)); WebSocketSessionHolder.addSession(loginUser.getUserId(), session);
log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType()); log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
} }

View File

@@ -113,7 +113,7 @@ public class WebSocketUtils {
* @param session WebSocket会话 * @param session WebSocket会话
* @param message 要发送的WebSocket消息对象 * @param message 要发送的WebSocket消息对象
*/ */
private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) { private synchronized static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
if (session == null || !session.isOpen()) { if (session == null || !session.isOpen()) {
log.warn("[send] session会话已经关闭"); log.warn("[send] session会话已经关闭");
} else { } else {

View File

@@ -74,7 +74,7 @@ public class WorkflowGlobalListener implements GlobalListener {
String ext = listenerVariable.getNode().getExt(); String ext = listenerVariable.getNode().getExt();
if (StringUtils.isNotBlank(ext)) { if (StringUtils.isNotBlank(ext)) {
Map<String, Object> variable = listenerVariable.getVariable(); Map<String, Object> variable = listenerVariable.getVariable();
if (CollUtil.isEmpty(variable)) { if (CollUtil.isNotEmpty(variable)) {
variable = new HashMap<>(); variable = new HashMap<>();
} }
NodeExtVo nodeExt = nodeExtService.parseNodeExt(ext, variable); NodeExtVo nodeExt = nodeExtService.parseNodeExt(ext, variable);