mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-11-14 22:57:13 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 232624aace | |||
| 2e9079a909 | |||
| c7bee0033e | |||
| efb84c936f | |||
| 4b77d5cb3f | |||
| e3433bed01 | |||
| 56edceec7e |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,3 +1,23 @@
|
|||||||
|
## [v2.7.3](https://github.com/continew-org/continew-starter/compare/v2.7.2...v2.7.3) (2024-11-15)
|
||||||
|
|
||||||
|
### ✨ 新特性
|
||||||
|
|
||||||
|
- 【cache/redisson】RedisUtils 新增 ZSet 相关方法 ([56edcee](https://github.com/continew-org/continew-starter/commit/56edceec7e7c61bbd06a1995c2351441302ac969))
|
||||||
|
- 【core】新增枚举校验器 EnumValue ([c7bee00](https://github.com/continew-org/continew-starter/commit/c7bee0033ef794784b9c9fd39f61a245abff0c62))
|
||||||
|
|
||||||
|
### 💎 功能优化
|
||||||
|
|
||||||
|
- 【extension/crud】查询详情命名调整,GET -> DETAIL,增加详情权限校验 ([4b77d5c](https://github.com/continew-org/continew-starter/commit/4b77d5cb3ff93e7d8d207196948352294c6cdcc6))
|
||||||
|
- 【core】拆分字符串常量和字符常量 ([2e9079a](https://github.com/continew-org/continew-starter/commit/2e9079a909db8df57ed7de49c95d9daeb9616f4a))
|
||||||
|
|
||||||
|
### 🐛 问题修复
|
||||||
|
|
||||||
|
- 【data/mp】修复普通枚举类型处理错误 ([efb84c9](https://github.com/continew-org/continew-starter/commit/efb84c936f1012c3ac4b6264599f6fb1f5ae5f97))
|
||||||
|
|
||||||
|
### 📦 依赖升级
|
||||||
|
|
||||||
|
- CosID 2.9.8 => 2.9.9 ([e3433be](https://github.com/continew-org/continew-starter/commit/e3433bed01e9bccc1179c04acc82df843434d9af))
|
||||||
|
|
||||||
## [v2.7.2](https://github.com/continew-org/continew-starter/compare/v2.7.1...v2.7.2) (2024-11-12)
|
## [v2.7.2](https://github.com/continew-org/continew-starter/compare/v2.7.1...v2.7.2) (2024-11-12)
|
||||||
|
|
||||||
### ✨ 新特性
|
### ✨ 新特性
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package top.continew.starter.apidoc.handler;
|
package top.continew.starter.apidoc.handler;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
import cn.hutool.core.util.ClassUtil;
|
import cn.hutool.core.util.ClassUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||||
import com.fasterxml.jackson.databind.type.SimpleType;
|
import com.fasterxml.jackson.databind.type.SimpleType;
|
||||||
import io.swagger.v3.core.converter.AnnotatedType;
|
import io.swagger.v3.core.converter.AnnotatedType;
|
||||||
@@ -52,7 +52,7 @@ public class BaseEnumParameterHandler implements ParameterCustomizer, PropertyCu
|
|||||||
return parameterModel;
|
return parameterModel;
|
||||||
}
|
}
|
||||||
String description = parameterModel.getDescription();
|
String description = parameterModel.getDescription();
|
||||||
if (StrUtil.contains(description, "color:red")) {
|
if (CharSequenceUtil.contains(description, "color:red")) {
|
||||||
return parameterModel;
|
return parameterModel;
|
||||||
}
|
}
|
||||||
// 自定义枚举描述并封装参数配置
|
// 自定义枚举描述并封装参数配置
|
||||||
|
|||||||
@@ -194,6 +194,167 @@ public class RedisUtils {
|
|||||||
return CLIENT.getKeys().getKeysStreamByPattern(pattern).toList();
|
return CLIENT.getKeys().getKeysStreamByPattern(pattern).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加元素到 ZSet 中
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @param score 分数
|
||||||
|
* @return true:添加成功;false:添加失败
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> boolean zAdd(String key, T value, double score) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.add(score, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 ZSet 中指定元素的分数
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @return 分数(null 表示元素不存在)
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> Double zScore(String key, T value) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.getScore(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 ZSet 中指定元素的排名
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @return 排名(从 0 开始,null 表示元素不存在)
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> Integer zRank(String key, T value) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.rank(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 ZSet 中的元素个数
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return 元素个数
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> int zSize(String key) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 ZSet 中删除指定元素
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @return true:删除成功;false:删除失败
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> boolean zRemove(String key, T value) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.remove(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 ZSet 中指定分数范围内的元素
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param min 最小分数(包含)
|
||||||
|
* @param max 最大分数(包含)
|
||||||
|
* @return 删除的元素个数
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> int zRemoveRangeByScore(String key, double min, double max) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.removeRangeByScore(min, true, max, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 ZSet 中指定排名范围内的元素
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 索引从 0 开始。<code>-1<code> 表示最高分,<code>-2<code> 表示第二高分。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param startIndex 起始索引
|
||||||
|
* @param endIndex 结束索引
|
||||||
|
* @return 删除的元素个数
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> int zRemoveRangeByRank(String key, int startIndex, int endIndex) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.removeRangeByRank(startIndex, endIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分数范围查询 ZSet 中的元素列表
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param min 最小分数(包含)
|
||||||
|
* @param max 最大分数(包含)
|
||||||
|
* @return 元素列表
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> Collection<T> zRangeByScore(String key, double min, double max) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.valueRange(min, true, max, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分数范围查询 ZSet 中的元素列表
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param min 最小分数(包含)
|
||||||
|
* @param max 最大分数(包含)
|
||||||
|
* @param offset 偏移量
|
||||||
|
* @param count 数量
|
||||||
|
* @return 元素列表
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> Collection<T> zRangeByScore(String key, double min, double max, int offset, int count) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.valueRange(min, true, max, true, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分数范围查询 ZSet 中的元素个数
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param min 最小分数(包含)
|
||||||
|
* @param max 最大分数(包含)
|
||||||
|
* @return 元素个数
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> int zCountRangeByScore(String key, double min, double max) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
return zSet.count(min, true, max, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算 ZSet 中多个元素的分数之和
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param values 值列表
|
||||||
|
* @return 分数之和
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public static <T> double zSum(String key, Collection<T> values) {
|
||||||
|
RScoredSortedSet<T> zSet = CLIENT.getScoredSortedSet(key);
|
||||||
|
double sum = 0;
|
||||||
|
for (T value : values) {
|
||||||
|
Double score = zSet.getScore(value);
|
||||||
|
if (score != null) {
|
||||||
|
sum += score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 限流
|
* 限流
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.continew.starter.core.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符相关常量
|
||||||
|
*
|
||||||
|
* @author looly(<a href="https://gitee.com/dromara/hutool">Hutool</a>)
|
||||||
|
* @author Charles7c
|
||||||
|
* @see cn.hutool.core.text.CharPool
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public class CharConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空格符 {@code ' '}
|
||||||
|
*/
|
||||||
|
public static final char SPACE = ' ';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 制表符 {@code '\t'}
|
||||||
|
*/
|
||||||
|
public static final char TAB = ' ';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点 {@code '.'}
|
||||||
|
*/
|
||||||
|
public static final char DOT = '.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逗号 {@code ','}
|
||||||
|
*/
|
||||||
|
public static final char COMMA = ',';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中文逗号 {@code ','}
|
||||||
|
*/
|
||||||
|
public static final char CHINESE_COMMA = ',';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 冒号 {@code ':'}
|
||||||
|
*/
|
||||||
|
public static final char COLON = ':';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分号 {@code ';'}
|
||||||
|
*/
|
||||||
|
public static final char SEMICOLON = ';';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 问号 {@code '?'}
|
||||||
|
*/
|
||||||
|
public static final char QUESTION_MARK = '?';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下划线 {@code '_'}
|
||||||
|
*/
|
||||||
|
public static final char UNDERLINE = '_';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 减号(连接符) {@code '-'}
|
||||||
|
*/
|
||||||
|
public static final char DASHED = '-';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 星号 {@code '*'}
|
||||||
|
*/
|
||||||
|
public static final char ASTERISK = '*';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 斜杠 {@code '/'}
|
||||||
|
*/
|
||||||
|
public static final char SLASH = '/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反斜杠 {@code '\\'}
|
||||||
|
*/
|
||||||
|
public static final char BACKSLASH = '\\';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管道符 {@code '|'}
|
||||||
|
*/
|
||||||
|
public static final char PIPE = '|';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 艾特 {@code '@'}
|
||||||
|
*/
|
||||||
|
public static final char AT = '@';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与符号 {@code '&'}
|
||||||
|
*/
|
||||||
|
public static final char AMP = '&';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 花括号(左) <code>'{'</code>
|
||||||
|
*/
|
||||||
|
public static final char DELIM_START = '{';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 花括号(右) <code>'}'</code>
|
||||||
|
*/
|
||||||
|
public static final char DELIM_END = '}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中括号(左) {@code '['}
|
||||||
|
*/
|
||||||
|
public static final char BRACKET_START = '[';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中括号(右) {@code ']'}
|
||||||
|
*/
|
||||||
|
public static final char BRACKET_END = ']';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 圆括号(左) {@code '('}
|
||||||
|
*/
|
||||||
|
public static final char ROUND_BRACKET_START = '(';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 圆括号(右) {@code ')'}
|
||||||
|
*/
|
||||||
|
public static final char ROUND_BRACKET_END = ')';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 双引号 {@code '"'}
|
||||||
|
*/
|
||||||
|
public static final char DOUBLE_QUOTES = '"';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单引号 {@code '\''}
|
||||||
|
*/
|
||||||
|
public static final char SINGLE_QUOTE = '\'';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等号 {@code '='}
|
||||||
|
*/
|
||||||
|
public static final char EQUALS = '=';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回车符 {@code '\r'}
|
||||||
|
*/
|
||||||
|
public static final char CR = '\r';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换行符 {@code '\n'}
|
||||||
|
*/
|
||||||
|
public static final char LF = '\n';
|
||||||
|
|
||||||
|
private CharConstants() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,253 +16,133 @@
|
|||||||
|
|
||||||
package top.continew.starter.core.constant;
|
package top.continew.starter.core.constant;
|
||||||
|
|
||||||
import cn.hutool.core.text.CharPool;
|
|
||||||
import cn.hutool.core.text.StrPool;
|
|
||||||
import cn.hutool.core.util.XmlUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符串相关常量
|
* 字符串相关常量
|
||||||
*
|
*
|
||||||
* @author looly
|
* @author looly(<a href="https://gitee.com/dromara/hutool">Hutool</a>)
|
||||||
* @author Charles7c
|
* @author Charles7c
|
||||||
|
* @see cn.hutool.core.text.StrPool
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public class StringConstants {
|
public class StringConstants {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符常量:空格符 {@code ' '}
|
* 空字符串 {@code ""}
|
||||||
*/
|
|
||||||
public static final char C_SPACE = CharPool.SPACE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:制表符 {@code '\t'}
|
|
||||||
*/
|
|
||||||
public static final char C_TAB = CharPool.TAB;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:点 {@code '.'}
|
|
||||||
*/
|
|
||||||
public static final char C_DOT = CharPool.DOT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:斜杠 {@code '/'}
|
|
||||||
*/
|
|
||||||
public static final char C_SLASH = CharPool.SLASH;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:反斜杠 {@code '\\'}
|
|
||||||
*/
|
|
||||||
public static final char C_BACKSLASH = CharPool.BACKSLASH;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:回车符 {@code '\r'}
|
|
||||||
*/
|
|
||||||
public static final char C_CR = CharPool.CR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:换行符 {@code '\n'}
|
|
||||||
*/
|
|
||||||
public static final char C_LF = CharPool.LF;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:下划线 {@code '_'}
|
|
||||||
*/
|
|
||||||
public static final char C_UNDERLINE = CharPool.UNDERLINE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:逗号 {@code ','}
|
|
||||||
*/
|
|
||||||
public static final char C_COMMA = CharPool.COMMA;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:花括号(左) <code>'{'</code>
|
|
||||||
*/
|
|
||||||
public static final char C_DELIM_START = CharPool.DELIM_START;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:花括号(右) <code>'}'</code>
|
|
||||||
*/
|
|
||||||
public static final char C_DELIM_END = CharPool.DELIM_END;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:中括号(左) {@code '['}
|
|
||||||
*/
|
|
||||||
public static final char C_BRACKET_START = CharPool.BRACKET_START;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:中括号(右) {@code ']'}
|
|
||||||
*/
|
|
||||||
public static final char C_BRACKET_END = CharPool.BRACKET_END;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:冒号 {@code ':'}
|
|
||||||
*/
|
|
||||||
public static final char C_COLON = CharPool.COLON;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:艾特 {@code '@'}
|
|
||||||
*/
|
|
||||||
public static final char C_AT = CharPool.AT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符常量:星号 {@code '*'}
|
|
||||||
*/
|
|
||||||
public static final char C_ASTERISK = '*';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:制表符 {@code "\t"}
|
|
||||||
*/
|
|
||||||
public static final String TAB = StrPool.TAB;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:点 {@code "."}
|
|
||||||
*/
|
|
||||||
public static final String DOT = StrPool.DOT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:双点 {@code ".."} <br> 用途:作为指向上级文件夹的路径,如:{@code "../path"}
|
|
||||||
*/
|
|
||||||
public static final String DOUBLE_DOT = StrPool.DOUBLE_DOT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:斜杠 {@code "/"}
|
|
||||||
*/
|
|
||||||
public static final String SLASH = StrPool.SLASH;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:反斜杠 {@code "\\"}
|
|
||||||
*/
|
|
||||||
public static final String BACKSLASH = StrPool.BACKSLASH;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:回车符 {@code "\r"} <br> 解释:该字符常用于表示 Linux 系统和 MacOS 系统下的文本换行
|
|
||||||
*/
|
|
||||||
public static final String CR = StrPool.CR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:换行符 {@code "\n"}
|
|
||||||
*/
|
|
||||||
public static final String LF = StrPool.LF;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:Windows 换行 {@code "\r\n"} <br> 解释:该字符串常用于表示 Windows 系统下的文本换行
|
|
||||||
*/
|
|
||||||
public static final String CRLF = StrPool.CRLF;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:下划线 {@code "_"}
|
|
||||||
*/
|
|
||||||
public static final String UNDERLINE = StrPool.UNDERLINE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:减号(连接符) {@code "-"}
|
|
||||||
*/
|
|
||||||
public static final String DASHED = StrPool.DASHED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:逗号 {@code ","}
|
|
||||||
*/
|
|
||||||
public static final String COMMA = StrPool.COMMA;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:花括号(左) <code>"{"</code>
|
|
||||||
*/
|
|
||||||
public static final String DELIM_START = StrPool.DELIM_START;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:花括号(右) <code>"}"</code>
|
|
||||||
*/
|
|
||||||
public static final String DELIM_END = StrPool.DELIM_END;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:中括号(左) {@code "["}
|
|
||||||
*/
|
|
||||||
public static final String BRACKET_START = StrPool.BRACKET_START;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:中括号(右) {@code "]"}
|
|
||||||
*/
|
|
||||||
public static final String BRACKET_END = StrPool.BRACKET_END;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:冒号 {@code ":"}
|
|
||||||
*/
|
|
||||||
public static final String COLON = StrPool.COLON;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:艾特 {@code "@"}
|
|
||||||
*/
|
|
||||||
public static final String AT = StrPool.AT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:HTML 不间断空格转义 {@code " " -> " "}
|
|
||||||
*/
|
|
||||||
public static final String HTML_NBSP = XmlUtil.NBSP;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:HTML And 符转义 {@code "&" -> "&"}
|
|
||||||
*/
|
|
||||||
public static final String HTML_AMP = XmlUtil.AMP;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:HTML 双引号转义 {@code """ -> "\""}
|
|
||||||
*/
|
|
||||||
public static final String HTML_QUOTE = XmlUtil.QUOTE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:HTML 单引号转义 {@code "&apos" -> "'"}
|
|
||||||
*/
|
|
||||||
public static final String HTML_APOS = XmlUtil.APOS;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:HTML 小于号转义 {@code "<" -> "<"}
|
|
||||||
*/
|
|
||||||
public static final String HTML_LT = XmlUtil.LT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:HTML 大于号转义 {@code ">" -> ">"}
|
|
||||||
*/
|
|
||||||
public static final String HTML_GT = XmlUtil.GT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字符串常量:空 JSON {@code "{}"}
|
|
||||||
*/
|
|
||||||
public static final String EMPTY_JSON = StrPool.EMPTY_JSON;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 空字符串
|
|
||||||
*/
|
*/
|
||||||
public static final String EMPTY = "";
|
public static final String EMPTY = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 空格
|
* 空格符 {@code " "}
|
||||||
*/
|
*/
|
||||||
public static final String SPACE = " ";
|
public static final String SPACE = " ";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分号
|
* 制表符 {@code "\t"}
|
||||||
|
*/
|
||||||
|
public static final String TAB = " ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空 JSON {@code "{}"}
|
||||||
|
*/
|
||||||
|
public static final String EMPTY_JSON = "{}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点 {@code "."}
|
||||||
|
*/
|
||||||
|
public static final String DOT = ".";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 双点 {@code ".."}
|
||||||
|
* <p>
|
||||||
|
* 作为指向上级文件夹的路径,如:{@code "../path"}
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public static final String DOUBLE_DOT = "..";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逗号 {@code ","}
|
||||||
|
*/
|
||||||
|
public static final String COMMA = ",";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中文逗号 {@code ","}
|
||||||
|
*/
|
||||||
|
public static final String CHINESE_COMMA = ",";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 冒号 {@code ":"}
|
||||||
|
*/
|
||||||
|
public static final String COLON = ":";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分号 {@code ";"}
|
||||||
*/
|
*/
|
||||||
public static final String SEMICOLON = ";";
|
public static final String SEMICOLON = ";";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 星号
|
* 问号 {@code "?"}
|
||||||
*/
|
|
||||||
public static final String ASTERISK = "*";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 问号
|
|
||||||
*/
|
*/
|
||||||
public static final String QUESTION_MARK = "?";
|
public static final String QUESTION_MARK = "?";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管道符
|
* 下划线 {@code "_"}
|
||||||
|
*/
|
||||||
|
public static final String UNDERLINE = "_";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 减号(连接符) {@code "-"}
|
||||||
|
*/
|
||||||
|
public static final String DASHED = "-";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 星号 {@code "*"}
|
||||||
|
*/
|
||||||
|
public static final String ASTERISK = "*";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 斜杠 {@code "/"}
|
||||||
|
*/
|
||||||
|
public static final String SLASH = "/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反斜杠 {@code "\\"}
|
||||||
|
*/
|
||||||
|
public static final String BACKSLASH = "\\";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管道符 {@code "|"}
|
||||||
*/
|
*/
|
||||||
public static final String PIPE = "|";
|
public static final String PIPE = "|";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 中文逗号
|
* 艾特 {@code "@"}
|
||||||
*/
|
*/
|
||||||
public static final String CHINESE_COMMA = ",";
|
public static final String AT = "@";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与符号 {@code "&"}
|
||||||
|
*/
|
||||||
|
public static final String AMP = "&";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 花括号(左) <code>"{"</code>
|
||||||
|
*/
|
||||||
|
public static final String DELIM_START = "{";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 花括号(右) <code>"}"</code>
|
||||||
|
*/
|
||||||
|
public static final String DELIM_END = "}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中括号(左) {@code "["}
|
||||||
|
*/
|
||||||
|
public static final String BRACKET_START = "[";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中括号(右) {@code "]"}
|
||||||
|
*/
|
||||||
|
public static final String BRACKET_END = "]";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 圆括号(左) {@code "("}
|
* 圆括号(左) {@code "("}
|
||||||
@@ -275,20 +155,70 @@ public class StringConstants {
|
|||||||
public static final String ROUND_BRACKET_END = ")";
|
public static final String ROUND_BRACKET_END = ")";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 等号(=)
|
* 双引号 {@code "\""}
|
||||||
|
*/
|
||||||
|
public static final String DOUBLE_QUOTES = "\"";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单引号 {@code "'"}
|
||||||
|
*/
|
||||||
|
public static final String SINGLE_QUOTE = "'";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等号 {@code "="}
|
||||||
*/
|
*/
|
||||||
public static final String EQUALS = "=";
|
public static final String EQUALS = "=";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路径模式
|
* 回车符 {@code "\r"}
|
||||||
|
*/
|
||||||
|
public static final String CR = "\r";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换行符 {@code "\n"}
|
||||||
|
*/
|
||||||
|
public static final String LF = "\n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路径模式 {@code "/**"}
|
||||||
*/
|
*/
|
||||||
public static final String PATH_PATTERN = "/**";
|
public static final String PATH_PATTERN = "/**";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路径模式(仅匹配当前目录)
|
* 路径模式(仅匹配当前目录) {@code "/*"}
|
||||||
*/
|
*/
|
||||||
public static final String PATH_PATTERN_CURRENT_DIR = "/*";
|
public static final String PATH_PATTERN_CURRENT_DIR = "/*";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML 不间断空格转义 {@code " " -> " "}
|
||||||
|
*/
|
||||||
|
public static final String HTML_NBSP = " ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML And 符转义 {@code "&" -> "&"}
|
||||||
|
*/
|
||||||
|
public static final String HTML_AMP = "&";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML 双引号转义 {@code """ -> "\""}
|
||||||
|
*/
|
||||||
|
public static final String HTML_QUOTE = """;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML 单引号转义 {@code "&apos" -> "'"}
|
||||||
|
*/
|
||||||
|
public static final String HTML_APOS = "'";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML 小于号转义 {@code "<" -> "<"}
|
||||||
|
*/
|
||||||
|
public static final String HTML_LT = "<";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTML 大于号转义 {@code ">" -> ">"}
|
||||||
|
*/
|
||||||
|
public static final String HTML_GT = ">";
|
||||||
|
|
||||||
private StringConstants() {
|
private StringConstants() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.continew.starter.core.validation;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
import top.continew.starter.core.constant.StringConstants;
|
||||||
|
import top.continew.starter.core.exception.BusinessException;
|
||||||
|
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务参数校验工具类(抛出 500 ServiceException)
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @see BusinessException
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class CheckUtils extends Validator {
|
||||||
|
|
||||||
|
private static final Class<BusinessException> EXCEPTION_TYPE = BusinessException.class;
|
||||||
|
|
||||||
|
private CheckUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不存在,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param entityName 实体名
|
||||||
|
* @param fieldName 字段名
|
||||||
|
* @param fieldValue 字段值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotExists(Object obj, String entityName, String fieldName, Object fieldValue) {
|
||||||
|
String message = "%s 为 [%s] 的 %s 记录已不存在".formatted(fieldName, fieldValue, CharSequenceUtil
|
||||||
|
.replace(entityName, "DO", StringConstants.EMPTY));
|
||||||
|
throwIfNull(obj, message, EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNull(Object obj, String template, Object... params) {
|
||||||
|
throwIfNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotNull(Object obj, String template, Object... params) {
|
||||||
|
throwIfNotNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果存在,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param entityName 实体名
|
||||||
|
* @param fieldName 字段名
|
||||||
|
* @param fieldValue 字段值
|
||||||
|
*/
|
||||||
|
public static void throwIfExists(Object obj, String entityName, String fieldName, Object fieldValue) {
|
||||||
|
String message = "%s 为 [%s] 的 %s 记录已存在".formatted(fieldName, fieldValue, entityName);
|
||||||
|
throwIfNotNull(obj, message, EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfEmpty(Object obj, String template, Object... params) {
|
||||||
|
throwIfEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotEmpty(Object obj, String template, Object... params) {
|
||||||
|
throwIfNotEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param str 被检测的字符串
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfBlank(CharSequence str, String template, Object... params) {
|
||||||
|
throwIfBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param str 被检测的字符串
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotBlank(CharSequence str, String template, Object... params) {
|
||||||
|
throwIfNotBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果相同,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj1 要比较的对象1
|
||||||
|
* @param obj2 要比较的对象2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfEqual(Object obj1, Object obj2, String template, Object... params) {
|
||||||
|
throwIfEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不相同,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj1 要比较的对象1
|
||||||
|
* @param obj2 要比较的对象2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotEqual(Object obj1, Object obj2, String template, Object... params) {
|
||||||
|
throwIfNotEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果相同,抛出异常(不区分大小写)
|
||||||
|
*
|
||||||
|
* @param str1 要比较的字符串1
|
||||||
|
* @param str2 要比较的字符串2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfEqualIgnoreCase(CharSequence str1, CharSequence str2, String template, Object... params) {
|
||||||
|
throwIfEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不相同,抛出异常(不区分大小写)
|
||||||
|
*
|
||||||
|
* @param str1 要比较的字符串1
|
||||||
|
* @param str2 要比较的字符串2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotEqualIgnoreCase(CharSequence str1,
|
||||||
|
CharSequence str2,
|
||||||
|
String template,
|
||||||
|
Object... params) {
|
||||||
|
throwIfNotEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果条件成立,抛出异常
|
||||||
|
*
|
||||||
|
* @param condition 条件
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIf(boolean condition, String template, Object... params) {
|
||||||
|
throwIf(condition, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果条件成立,抛出异常
|
||||||
|
*
|
||||||
|
* @param conditionSupplier 条件
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIf(BooleanSupplier conditionSupplier, String template, Object... params) {
|
||||||
|
throwIf(conditionSupplier, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.continew.starter.core.validation;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
import top.continew.starter.core.exception.BadRequestException;
|
||||||
|
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基本参数校验工具类(抛出 400 BadRequestException)
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @see BadRequestException
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class ValidationUtils extends Validator {
|
||||||
|
|
||||||
|
private static final Class<BadRequestException> EXCEPTION_TYPE = BadRequestException.class;
|
||||||
|
|
||||||
|
private ValidationUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNull(Object obj, String template, Object... params) {
|
||||||
|
throwIfNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotNull(Object obj, String template, Object... params) {
|
||||||
|
throwIfNotNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfEmpty(Object obj, String template, Object... params) {
|
||||||
|
throwIfEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotEmpty(Object obj, String template, Object... params) {
|
||||||
|
throwIfNotEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param str 被检测的字符串
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfBlank(CharSequence str, String template, Object... params) {
|
||||||
|
throwIfBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param str 被检测的字符串
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotBlank(CharSequence str, String template, Object... params) {
|
||||||
|
throwIfNotBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果相同,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj1 要比较的对象1
|
||||||
|
* @param obj2 要比较的对象2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfEqual(Object obj1, Object obj2, String template, Object... params) {
|
||||||
|
throwIfEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不相同,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj1 要比较的对象1
|
||||||
|
* @param obj2 要比较的对象2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotEqual(Object obj1, Object obj2, String template, Object... params) {
|
||||||
|
throwIfNotEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果相同,抛出异常(不区分大小写)
|
||||||
|
*
|
||||||
|
* @param str1 要比较的字符串1
|
||||||
|
* @param str2 要比较的字符串2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfEqualIgnoreCase(CharSequence str1, CharSequence str2, String template, Object... params) {
|
||||||
|
throwIfEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不相同,抛出异常(不区分大小写)
|
||||||
|
*
|
||||||
|
* @param str1 要比较的字符串1
|
||||||
|
* @param str2 要比较的字符串2
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIfNotEqualIgnoreCase(CharSequence str1,
|
||||||
|
CharSequence str2,
|
||||||
|
String template,
|
||||||
|
Object... params) {
|
||||||
|
throwIfNotEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果条件成立,抛出异常
|
||||||
|
*
|
||||||
|
* @param condition 条件
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIf(boolean condition, String template, Object... params) {
|
||||||
|
throwIf(condition, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果条件成立,抛出异常
|
||||||
|
*
|
||||||
|
* @param conditionSupplier 条件
|
||||||
|
* @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null"
|
||||||
|
* @param params 参数值
|
||||||
|
*/
|
||||||
|
public static void throwIf(BooleanSupplier conditionSupplier, String template, Object... params) {
|
||||||
|
throwIf(conditionSupplier, CharSequenceUtil.format(template, params), EXCEPTION_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.continew.starter.core.validation;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import jakarta.validation.ConstraintViolation;
|
||||||
|
import jakarta.validation.ConstraintViolationException;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验器
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class Validator {
|
||||||
|
|
||||||
|
private static final jakarta.validation.Validator VALIDATOR = SpringUtil
|
||||||
|
.getBean(jakarta.validation.Validator.class);
|
||||||
|
|
||||||
|
protected Validator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfNull(Object obj, String message, Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(null == obj, message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfNotNull(Object obj, String message, Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(null != obj, message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfEmpty(Object obj, String message, Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(ObjectUtil.isEmpty(obj), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj 被检测的对象
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfNotEmpty(Object obj, String message, Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(ObjectUtil.isNotEmpty(obj), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param str 被检测的字符串
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfBlank(CharSequence str,
|
||||||
|
String message,
|
||||||
|
Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(CharSequenceUtil.isBlank(str), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不为空,抛出异常
|
||||||
|
*
|
||||||
|
* @param str 被检测的字符串
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfNotBlank(CharSequence str,
|
||||||
|
String message,
|
||||||
|
Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(CharSequenceUtil.isNotBlank(str), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果相同,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj1 要比较的对象1
|
||||||
|
* @param obj2 要比较的对象2
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfEqual(Object obj1,
|
||||||
|
Object obj2,
|
||||||
|
String message,
|
||||||
|
Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(ObjectUtil.equal(obj1, obj2), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不相同,抛出异常
|
||||||
|
*
|
||||||
|
* @param obj1 要比较的对象1
|
||||||
|
* @param obj2 要比较的对象2
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfNotEqual(Object obj1,
|
||||||
|
Object obj2,
|
||||||
|
String message,
|
||||||
|
Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(ObjectUtil.notEqual(obj1, obj2), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果相同,抛出异常(不区分大小写)
|
||||||
|
*
|
||||||
|
* @param str1 要比较的字符串1
|
||||||
|
* @param str2 要比较的字符串2
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfEqualIgnoreCase(CharSequence str1,
|
||||||
|
CharSequence str2,
|
||||||
|
String message,
|
||||||
|
Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(CharSequenceUtil.equalsIgnoreCase(str1, str2), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果不相同,抛出异常(不区分大小写)
|
||||||
|
*
|
||||||
|
* @param str1 要比较的字符串1
|
||||||
|
* @param str2 要比较的字符串2
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIfNotEqualIgnoreCase(CharSequence str1,
|
||||||
|
CharSequence str2,
|
||||||
|
String message,
|
||||||
|
Class<? extends RuntimeException> exceptionType) {
|
||||||
|
throwIf(!CharSequenceUtil.equalsIgnoreCase(str1, str2), message, exceptionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果条件成立,抛出异常
|
||||||
|
*
|
||||||
|
* @param condition 条件
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIf(boolean condition, String message, Class<? extends RuntimeException> exceptionType) {
|
||||||
|
if (condition) {
|
||||||
|
throw ReflectUtil.newInstance(exceptionType, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果条件成立,抛出异常
|
||||||
|
*
|
||||||
|
* @param conditionSupplier 条件
|
||||||
|
* @param message 错误信息
|
||||||
|
* @param exceptionType 异常类型
|
||||||
|
*/
|
||||||
|
protected static void throwIf(BooleanSupplier conditionSupplier,
|
||||||
|
String message,
|
||||||
|
Class<? extends RuntimeException> exceptionType) {
|
||||||
|
if (null != conditionSupplier && conditionSupplier.getAsBoolean()) {
|
||||||
|
throw ReflectUtil.newInstance(exceptionType, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSR 303 校验
|
||||||
|
*
|
||||||
|
* @param obj 被校验对象
|
||||||
|
* @param groups 分组
|
||||||
|
* @since 2.3.0
|
||||||
|
*/
|
||||||
|
public static void validate(Object obj, Class<?>... groups) {
|
||||||
|
Set<ConstraintViolation<Object>> violations = VALIDATOR.validate(obj, groups);
|
||||||
|
if (!violations.isEmpty()) {
|
||||||
|
throw new ConstraintViolationException(violations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.continew.starter.core.validation.constraints;
|
||||||
|
|
||||||
|
import jakarta.validation.Constraint;
|
||||||
|
import jakarta.validation.Payload;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举校验注解
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* {@code @EnumValue(value = XxxEnum.class, message = "参数值非法")} <br />
|
||||||
|
* {@code @EnumValue(enumValues = {"F", "M"} ,message = "性别只允许为F或M")}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Jasmine
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Constraint(validatedBy = EnumValueValidator.class)
|
||||||
|
public @interface EnumValue {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举类
|
||||||
|
*
|
||||||
|
* @return 枚举类
|
||||||
|
*/
|
||||||
|
Class<? extends Enum> value() default Enum.class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举值
|
||||||
|
*
|
||||||
|
* @return 枚举值
|
||||||
|
*/
|
||||||
|
String[] enumValues() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取枚举值的方法名
|
||||||
|
*
|
||||||
|
* @return 获取枚举值的方法名
|
||||||
|
*/
|
||||||
|
String method() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提示消息
|
||||||
|
*
|
||||||
|
* @return 提示消息
|
||||||
|
*/
|
||||||
|
String message() default "参数值非法";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组
|
||||||
|
*
|
||||||
|
* @return 分组
|
||||||
|
*/
|
||||||
|
Class<?>[] groups() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 负载
|
||||||
|
*
|
||||||
|
* @return 负载
|
||||||
|
*/
|
||||||
|
Class<? extends Payload>[] payload() default {};
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.continew.starter.core.validation.constraints;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
import jakarta.validation.ConstraintValidator;
|
||||||
|
import jakarta.validation.ConstraintValidatorContext;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举校验注解校验器
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @author Jasmine
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public class EnumValueValidator implements ConstraintValidator<EnumValue, Object> {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(EnumValueValidator.class);
|
||||||
|
private Class<? extends Enum> enumClass;
|
||||||
|
private String[] enumValues;
|
||||||
|
private String enumMethod;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(EnumValue enumValue) {
|
||||||
|
this.enumClass = enumValue.value();
|
||||||
|
this.enumValues = enumValue.enumValues();
|
||||||
|
this.enumMethod = enumValue.method();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||||
|
if (value == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 优先校验 enumValues
|
||||||
|
if (enumValues.length > 0) {
|
||||||
|
return Arrays.asList(enumValues).contains(value.toString());
|
||||||
|
}
|
||||||
|
Enum[] enumConstants = enumClass.getEnumConstants();
|
||||||
|
if (enumConstants.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (CharSequenceUtil.isBlank(enumMethod)) {
|
||||||
|
return findEnumValue(enumConstants, Enum::toString, value.toString());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 枚举类指定了方法名,则调用指定方法获取枚举值
|
||||||
|
Method method = enumClass.getMethod(enumMethod);
|
||||||
|
for (Enum enumConstant : enumConstants) {
|
||||||
|
if (method.invoke(enumConstant).equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("An error occurred while validating the enum value, please check the @EnumValue parameter configuration.", e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 遍历枚举类,判断是否包含指定值
|
||||||
|
*
|
||||||
|
* @param enumConstants 枚举类数组
|
||||||
|
* @param function 获取枚举值的函数
|
||||||
|
* @param value 待校验的值
|
||||||
|
* @return 是否包含指定值
|
||||||
|
*/
|
||||||
|
private boolean findEnumValue(Enum[] enumConstants, Function<Enum, Object> function, Object value) {
|
||||||
|
for (Enum enumConstant : enumConstants) {
|
||||||
|
if (function.apply(enumConstant).equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package top.continew.starter.data.mf.datapermission;
|
package top.continew.starter.data.mf.datapermission;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
|
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ public class DataPermissionDialect extends CommonsDialectImpl {
|
|||||||
* @return 带表别名字段
|
* @return 带表别名字段
|
||||||
*/
|
*/
|
||||||
private String buildColumn(String tableAlias, String columnName) {
|
private String buildColumn(String tableAlias, String columnName) {
|
||||||
if (StrUtil.isNotEmpty(tableAlias)) {
|
if (CharSequenceUtil.isNotEmpty(tableAlias)) {
|
||||||
return "%s.%s".formatted(tableAlias, columnName);
|
return "%s.%s".formatted(tableAlias, columnName);
|
||||||
}
|
}
|
||||||
return columnName;
|
return columnName;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import top.continew.starter.core.exception.BadRequestException;
|
import top.continew.starter.core.exception.BadRequestException;
|
||||||
import top.continew.starter.core.util.ReflectUtils;
|
import top.continew.starter.core.util.ReflectUtils;
|
||||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
import top.continew.starter.core.validation.ValidationUtils;
|
||||||
import top.continew.starter.data.core.annotation.Query;
|
import top.continew.starter.data.core.annotation.Query;
|
||||||
import top.continew.starter.data.core.annotation.QueryIgnore;
|
import top.continew.starter.data.core.annotation.QueryIgnore;
|
||||||
import top.continew.starter.data.core.enums.QueryType;
|
import top.continew.starter.data.core.enums.QueryType;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|||||||
import top.continew.starter.core.constant.PropertiesConstants;
|
import top.continew.starter.core.constant.PropertiesConstants;
|
||||||
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
import top.continew.starter.core.util.GeneralPropertySourceFactory;
|
||||||
import top.continew.starter.data.mp.autoconfigure.idgenerator.MyBatisPlusIdGeneratorConfiguration;
|
import top.continew.starter.data.mp.autoconfigure.idgenerator.MyBatisPlusIdGeneratorConfiguration;
|
||||||
import top.continew.starter.data.mp.handler.MybatisBaseEnumTypeHandler;
|
import top.continew.starter.data.mp.handler.CompositeBaseEnumTypeHandler;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -63,7 +63,8 @@ public class MybatisPlusAutoConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public MybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizer() {
|
public MybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizer() {
|
||||||
return properties -> properties.getConfiguration().setDefaultEnumTypeHandler(MybatisBaseEnumTypeHandler.class);
|
return properties -> properties.getConfiguration()
|
||||||
|
.setDefaultEnumTypeHandler(CompositeBaseEnumTypeHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.continew.starter.data.mp.handler;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
|
import org.apache.ibatis.type.EnumTypeHandler;
|
||||||
|
import org.apache.ibatis.type.JdbcType;
|
||||||
|
import org.apache.ibatis.type.TypeException;
|
||||||
|
import org.apache.ibatis.type.TypeHandler;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复合枚举类型处理器(扩展 BaseEnum 支持)
|
||||||
|
*
|
||||||
|
* @author miemie(<a href="https://gitee.com/baomidou/mybatis-plus">MyBatis Plus</a>)
|
||||||
|
* @author Charles7c
|
||||||
|
* @see com.baomidou.mybatisplus.core.handlers.CompositeEnumTypeHandler
|
||||||
|
* @since 2.7.3
|
||||||
|
*/
|
||||||
|
public class CompositeBaseEnumTypeHandler<E extends Enum<E>> implements TypeHandler<E> {
|
||||||
|
|
||||||
|
private static final Map<Class<?>, Boolean> MP_ENUM_CACHE = new ConcurrentHashMap<>();
|
||||||
|
private static Class<? extends TypeHandler> defaultEnumTypeHandler = EnumTypeHandler.class;
|
||||||
|
private final TypeHandler<E> delegate;
|
||||||
|
|
||||||
|
public CompositeBaseEnumTypeHandler(Class<E> enumClassType) {
|
||||||
|
if (enumClassType == null) {
|
||||||
|
throw new IllegalArgumentException("Type argument cannot be null");
|
||||||
|
}
|
||||||
|
if (Boolean.TRUE.equals(CollectionUtils
|
||||||
|
.computeIfAbsent(MP_ENUM_CACHE, enumClassType, MybatisBaseEnumTypeHandler::isMpEnums))) {
|
||||||
|
delegate = new MybatisBaseEnumTypeHandler<>(enumClassType);
|
||||||
|
} else {
|
||||||
|
delegate = getInstance(enumClassType, defaultEnumTypeHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDefaultEnumTypeHandler(Class<? extends TypeHandler> defaultEnumTypeHandler) {
|
||||||
|
if (defaultEnumTypeHandler != null && !MybatisBaseEnumTypeHandler.class
|
||||||
|
.isAssignableFrom(defaultEnumTypeHandler)) {
|
||||||
|
CompositeBaseEnumTypeHandler.defaultEnumTypeHandler = defaultEnumTypeHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
|
||||||
|
delegate.setParameter(ps, i, parameter, jdbcType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getResult(ResultSet rs, String columnName) throws SQLException {
|
||||||
|
return delegate.getResult(rs, columnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||||
|
return delegate.getResult(rs, columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||||
|
return delegate.getResult(cs, columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> TypeHandler<T> getInstance(Class<?> javaTypeClass, Class<?> typeHandlerClass) {
|
||||||
|
if (javaTypeClass != null) {
|
||||||
|
try {
|
||||||
|
Constructor<?> c = typeHandlerClass.getConstructor(Class.class);
|
||||||
|
return (TypeHandler<T>)c.newInstance(javaTypeClass);
|
||||||
|
} catch (NoSuchMethodException ignored) {
|
||||||
|
// ignored
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new TypeException("Failed invoking constructor for handler " + typeHandlerClass, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Constructor<?> c = typeHandlerClass.getConstructor();
|
||||||
|
return (TypeHandler<T>)c.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new TypeException("Unable to find a usable constructor for " + typeHandlerClass, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,10 +43,11 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义枚举属性转换器
|
* 枚举类型处理器(扩展 BaseEnum 支持)
|
||||||
*
|
*
|
||||||
* @author hubin
|
* @author hubin(<a href="https://gitee.com/baomidou/mybatis-plus">MyBatis Plus</a>)
|
||||||
* @author Charles7c
|
* @author Charles7c
|
||||||
|
* @see com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*/
|
*/
|
||||||
public class MybatisBaseEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
|
public class MybatisBaseEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package top.continew.starter.data.mp.service.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.util.ClassUtil;
|
import cn.hutool.core.util.ClassUtil;
|
||||||
import top.continew.starter.core.util.ReflectUtils;
|
import top.continew.starter.core.util.ReflectUtils;
|
||||||
import top.continew.starter.core.util.validate.CheckUtils;
|
import top.continew.starter.core.validation.CheckUtils;
|
||||||
import top.continew.starter.data.mp.base.BaseMapper;
|
import top.continew.starter.data.mp.base.BaseMapper;
|
||||||
import top.continew.starter.data.mp.service.IService;
|
import top.continew.starter.data.mp.service.IService;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import top.continew.starter.core.exception.BadRequestException;
|
import top.continew.starter.core.exception.BadRequestException;
|
||||||
import top.continew.starter.core.util.ReflectUtils;
|
import top.continew.starter.core.util.ReflectUtils;
|
||||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
import top.continew.starter.core.validation.ValidationUtils;
|
||||||
import top.continew.starter.data.core.annotation.Query;
|
import top.continew.starter.data.core.annotation.Query;
|
||||||
import top.continew.starter.data.core.annotation.QueryIgnore;
|
import top.continew.starter.data.core.annotation.QueryIgnore;
|
||||||
import top.continew.starter.data.core.enums.QueryType;
|
import top.continew.starter.data.core.enums.QueryType;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- 项目版本号 -->
|
<!-- 项目版本号 -->
|
||||||
<revision>2.7.2</revision>
|
<revision>2.7.3</revision>
|
||||||
<snail-job.version>1.1.2</snail-job.version>
|
<snail-job.version>1.1.2</snail-job.version>
|
||||||
<sa-token.version>1.39.0</sa-token.version>
|
<sa-token.version>1.39.0</sa-token.version>
|
||||||
<just-auth.version>1.16.6</just-auth.version>
|
<just-auth.version>1.16.6</just-auth.version>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<jetcache.version>2.7.6</jetcache.version>
|
<jetcache.version>2.7.6</jetcache.version>
|
||||||
<redisson.version>3.36.0</redisson.version>
|
<redisson.version>3.36.0</redisson.version>
|
||||||
<cosid.version>2.9.8</cosid.version>
|
<cosid.version>2.9.9</cosid.version>
|
||||||
<sms4j.version>3.3.3</sms4j.version>
|
<sms4j.version>3.3.3</sms4j.version>
|
||||||
<aj-captcha.version>1.3.0</aj-captcha.version>
|
<aj-captcha.version>1.3.0</aj-captcha.version>
|
||||||
<easy-captcha.version>1.6.2</easy-captcha.version>
|
<easy-captcha.version>1.6.2</easy-captcha.version>
|
||||||
|
|||||||
@@ -39,5 +39,5 @@ public @interface CrudRequestMapping {
|
|||||||
/**
|
/**
|
||||||
* API 列表
|
* API 列表
|
||||||
*/
|
*/
|
||||||
Api[] api() default {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT};
|
Api[] api() default {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public enum Api {
|
|||||||
/**
|
/**
|
||||||
* 详情
|
* 详情
|
||||||
*/
|
*/
|
||||||
GET,
|
DETAIL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增
|
* 新增
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
|||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public D get(@PathVariable("id") Long id) {
|
public D detail(@PathVariable("id") Long id) {
|
||||||
this.checkPermission(Api.LIST);
|
this.checkPermission(Api.DETAIL);
|
||||||
return baseService.get(id);
|
return baseService.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
|||||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public D get(@PathVariable("id") Long id) {
|
public D detail(@PathVariable("id") Long id) {
|
||||||
this.checkPermission(Api.LIST);
|
this.checkPermission(Api.DETAIL);
|
||||||
return baseService.get(id);
|
return baseService.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package top.continew.starter.security.mask.annotation;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import top.continew.starter.core.constant.StringConstants;
|
import top.continew.starter.core.constant.CharConstants;
|
||||||
import top.continew.starter.security.mask.core.JsonMaskSerializer;
|
import top.continew.starter.security.mask.core.JsonMaskSerializer;
|
||||||
import top.continew.starter.security.mask.enums.MaskType;
|
import top.continew.starter.security.mask.enums.MaskType;
|
||||||
import top.continew.starter.security.mask.strategy.IMaskStrategy;
|
import top.continew.starter.security.mask.strategy.IMaskStrategy;
|
||||||
@@ -72,5 +72,5 @@ public @interface JsonMask {
|
|||||||
/**
|
/**
|
||||||
* 脱敏符号(默认:*)
|
* 脱敏符号(默认:*)
|
||||||
*/
|
*/
|
||||||
char character() default StringConstants.C_ASTERISK;
|
char character() default CharConstants.ASTERISK;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user