AssertUtil 注释

CacheConfig缓存时间
sa Token NotLoginException异常响应优化
SqlUtil 修改
PageUtil封装
This commit is contained in:
2025-02-12 09:48:54 +08:00
parent dfaab353f7
commit 49996f5277
10 changed files with 186 additions and 185 deletions

View File

@@ -32,8 +32,8 @@ public class CacheConfig {
.serializeKeysWith(org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
// 设置值的序列化方式,使用 Fastjson2 序列化
.serializeValuesWith(org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair.fromSerializer(fastJson2RedisSerializer))
// 设置缓存过期时间为 30 分钟
.entryTtl(Duration.ofMinutes(30));
// 设置缓存过期时间为 120 分钟
.entryTtl(Duration.ofMinutes(120));
// 创建 Redis 缓存管理器
return RedisCacheManager.builder(redisConnectionFactory)

View File

@@ -41,7 +41,7 @@ public class CzgControllerAdvice {
@ResponseStatus(HttpStatus.OK)
public CzgResult<Object> notLoginErrorHandler(NotLoginException ex) {
setErrorLog(ex);
return CzgResult.failure(CzgRespCode.NOT_LOGIN);
return CzgResult.failure(CzgRespCode.NOT_LOGIN + ":" + ex.getMessage());
}
@ResponseBody
@@ -90,12 +90,13 @@ public class CzgControllerAdvice {
* 处理Hutool的校验工具类抛出异常
*/
@ExceptionHandler(ValidateException.class)
public CzgResult<Object> handleHutoolValidateException(ValidateException ex) {
public CzgResult<Object> handleValidateException(ValidateException ex) {
return CzgResult.failure(CzgRespCode.PARAM_ERROR.getCode(), ex.getMessage());
}
@ExceptionHandler(DuplicateKeyException.class)
public CzgResult handleDuplicateKeyException(DuplicateKeyException ex) {
public CzgResult<Object> handleDuplicateKeyException(DuplicateKeyException ex) {
setErrorLog(ex);
return CzgResult.failure(CzgRespCode.RECORD_EXISTED);
}

View File

@@ -1,79 +0,0 @@
package com.czg.core.page;
import cn.hutool.core.convert.Convert;
import com.czg.utils.ServletUtil;
import com.mybatisflex.core.paginate.Page;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 分页查询实体类
*
* @author Cashier
*/
@Data
public class PageQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 当前记录起始索引
*/
public static final String PAGE = "page";
/**
* 每页显示记录数
*/
public static final String SIZE = "size";
/**
* 分页大小
*/
private Integer size;
/**
* 当前页数
*/
private Integer page;
/**
* 排序列
*/
private String orderField;
/**
* 排序的方向desc或者asc
*/
private String order;
/**
* 当前记录起始索引 默认值
*/
public static final int DEFAULT_PAGE = 1;
/**
* 每页显示记录数 默认值 默认查全部
*/
public static final int DEFAULT_SIZE = 10;
/**
* 构造分页查询参数
*
* @param <T>
* @return
*/
public static <T> Page<T> build() {
Integer pageNum = Convert.toInt(ServletUtil.getParameter(PAGE), DEFAULT_PAGE);
Integer pageSize = Convert.toInt(ServletUtil.getParameter(SIZE), DEFAULT_SIZE);
if (pageNum <= 0) {
pageNum = DEFAULT_PAGE;
}
Page<T> page = new Page<>(pageNum, pageSize);
return page;
}
}

View File

@@ -1,49 +0,0 @@
package com.czg.core.page;
import cn.hutool.core.convert.Convert;
import com.czg.utils.ServletUtil;
/**
* 表格数据处理
*
* @author Cashier
*/
public class TableSupport {
/**
* 当前记录起始索引
*/
public static final String PAGE = "page";
/**
* 每页显示记录数
*/
public static final String SIZE = "size";
/**
* 排序字段,多个用逗号分隔
*/
public static final String ORDER_FIELD = "orderField";
/**
* 排序方式多个用逗号分隔asc:升序,desc:降序
*/
public static final String ORDER = "order";
/**
* 封装分页对象
*/
public static PageDomain getPageDomain() {
PageDomain pageDomain = new PageDomain();
pageDomain.setPage(Convert.toInt(ServletUtil.getParameter(PAGE), 1));
pageDomain.setSize(Convert.toInt(ServletUtil.getParameter(SIZE), 10));
pageDomain.setOrderField(ServletUtil.getParameter(ORDER_FIELD));
pageDomain.setOrder(ServletUtil.getParameter(ORDER));
return pageDomain;
}
public static PageDomain buildPageRequest() {
return getPageDomain();
}
}

View File

@@ -1,5 +1,3 @@
package com.czg.utils;
import cn.hutool.core.collection.CollUtil;
@@ -19,53 +17,123 @@ import java.util.Map;
*/
public class AssertUtil {
/**
* 检查字符串是否不为空或空白字符,如果为空或空白字符则抛出异常
*
* @param str 要检查的字符串
* @param msg 异常信息
* @throws ValidateException 如果字符串为空或空白字符
*/
public static void isBlank(String str, String msg) {
if (StrUtil.isBlank(str)) {
throw new ValidateException(msg);
}
}
/**
* 检查字符串是否不为空或空白字符,如果为空或空白字符则抛出异常
*
* @param str 要检查的字符串
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果字符串为空或空白字符
*/
public static void isBlank(String str, String errorMsgTemplate, Object... params) {
isBlank(str, StrUtil.format(errorMsgTemplate, params));
}
/**
* 检查对象是否不为 null如果为 null 则抛出异常
*
* @param object 要检查的对象
* @param msg 异常信息
* @throws ValidateException 如果对象为 null
*/
public static void isNull(Object object, String msg) {
if (object == null) {
throw new ValidateException(msg);
}
}
/**
* 检查对象是否不为 null如果为 null 则抛出异常
*
* @param object 要检查的对象
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果对象为 null
*/
public static void isNull(Object object, String errorMsgTemplate, Object... params) {
isNull(object, StrUtil.format(errorMsgTemplate, params));
}
/**
* 检查数组是否不为空,如果为空则抛出异常
*
* @param array 要检查的数组
* @param msg 异常信息
* @throws ValidateException 如果数组为空
*/
public static void isArrayEmpty(Object[] array, String msg) {
if (ArrayUtil.isEmpty(array)) {
throw new ValidateException(msg);
}
}
/**
* 检查数组是否不为空,如果为空则抛出异常
*
* @param array 要检查的数组
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果数组为空
*/
public static void isArrayEmpty(Object[] array, String errorMsgTemplate, Object... params) {
isArrayEmpty(array, StrUtil.format(errorMsgTemplate, params));
}
/**
* 检查列表是否不为空,如果为空则抛出异常
*
* @param list 要检查的列表
* @param msg 异常信息
* @throws ValidateException 如果列表为空
*/
public static void isListEmpty(List<?> list, String msg) {
if (CollUtil.isEmpty(list)) {
throw new ValidateException(msg);
}
}
/**
* 检查列表是否不为空,如果为空则抛出异常
*
* @param list 要检查的列表
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果列表为空
*/
public static void isListEmpty(List<?> list, String errorMsgTemplate, Object... params) {
isListEmpty(list, StrUtil.format(errorMsgTemplate, params));
}
public static void isMapEmpty(Map map, String msg) {
/**
* 检查 Map 是否不为空,如果为空则抛出异常
*
* @param <K> Map 的键类型
* @param <V> Map 的值类型
* @param map 要检查的 Map
* @param msg 异常信息
* @throws ValidateException 如果 Map 为空
*/
public static <K, V> void isMapEmpty(Map<K, V> map, String msg) {
if (MapUtil.isEmpty(map)) {
throw new ValidateException(msg);
}
}
public static void isMapEmpty(Map map, String errorMsgTemplate, Object... params) {
/**
* 检查 Map 是否不为空,如果为空则抛出异常
*
* @param <K> Map 的键类型
* @param <V> Map 的值类型
* @param map 要检查的 Map
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果 Map 为空
*/
public static <K, V> void isMapEmpty(Map<K, V> map, String errorMsgTemplate, Object... params) {
isMapEmpty(map, StrUtil.format(errorMsgTemplate, params));
}
}

View File

@@ -1,29 +1,104 @@
package com.czg.utils;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.czg.core.page.PageDomain;
import com.czg.core.page.TableSupport;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass;
/**
* 分页工具类
*
* @author tankaikai
* @since 2025-02-11 16:56
*/
@UtilityClass
public class PageUtil {
/**
* 构造分页排序条件
* 当前记录起始索引
*/
public static final String PAGE = "page";
/**
* 每页显示记录数
*/
public static final String SIZE = "size";
/**
* 排序字段,多个用逗号分隔
*/
public static final String ORDER_FIELD = "orderField";
/**
* 排序方式多个用逗号分隔asc:升序,desc:降序
*/
public static final String ORDER = "order";
/**
* 当前记录起始索引 默认值
*/
public static final int DEFAULT_PAGE = 1;
/**
* 每页显示记录数 默认值 默认查全部
*/
public static final int DEFAULT_SIZE = 10;
/**
* 构造分页Page
* <p>
* 从param体获取 (url请求 ?拼接的参数)
* page 默认1
* size 默认10
* <p>
*
* @return Page<T>
*/
public static <T> Page<T> buildPage() {
HttpServletRequest request = ServletUtil.getRequest();
Integer pageNum = Convert.toInt(request, DEFAULT_PAGE);
Integer pageSize = Convert.toInt(request, DEFAULT_SIZE);
if (pageNum <= 0) {
pageNum = DEFAULT_PAGE;
}
return new Page<>(pageNum, pageSize);
}
/**
* 构造分页QueryWrapper
* <p>
* 从param体获取 (url请求 ?拼接的参数)
* page 默认1
* size 默认10
* <p>
* orderField 排序字段列 驼峰命名 多个用逗号分隔
* order排序规则 asc,desc 多个条件逗号分割
*
* @return QueryWrapper
*/
public QueryWrapper buildPageQueryWrapper(){
public static QueryWrapper buildPageQueryWrapper() {
QueryWrapper queryWrapper = QueryWrapper.create();
PageDomain pageDomain = TableSupport.buildPageRequest();
PageDomain pageDomain = buildPageAndSortRequest();
if (StrUtil.isNotEmpty(pageDomain.getOrderBy())) {
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
queryWrapper.orderBy(orderBy);
}
return queryWrapper;
}
/**
* 封装分页对象
*/
private static PageDomain buildPageAndSortRequest() {
PageDomain pageDomain = new PageDomain();
HttpServletRequest request = ServletUtil.getRequest();
pageDomain.setPage(Convert.toInt(request.getParameter(PAGE), 1));
pageDomain.setSize(Convert.toInt(request.getParameter(SIZE), 10));
pageDomain.setOrderField(request.getParameter(ORDER_FIELD));
pageDomain.setOrder(request.getParameter(ORDER));
return pageDomain;
}
}

View File

@@ -1,25 +1,23 @@
package com.czg.utils;
import cn.hutool.core.util.StrUtil;
import java.util.List;
import java.util.regex.Pattern;
/**
* sql操作工具类
*
* @author ruoyi
*/
public class SqlUtil
{
public class SqlUtil {
/**
* 定义常用的 sql关键字
*/
public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()";
private static final Pattern SQL_KEYWORD_PATTERN = Pattern.compile("(?i)(and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |\\+|user\\(\\))");
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
private static final Pattern SQL_PATTERN = Pattern.compile("[a-zA-Z0-9_\\ \\,\\.]+");
/**
* 限制orderBy最大长度
@@ -29,15 +27,14 @@ public class SqlUtil
/**
* 检查字符,防止注入绕过
*/
public static String escapeOrderBySql(String value)
{
if (StrUtil.isNotEmpty(value) && !isValidOrderBySql(value))
{
throw new IllegalArgumentException("参数不符合规范,不能进行查询");
}
if (StrUtil.length(value) > ORDER_BY_MAX_LENGTH)
{
throw new IllegalArgumentException("参数已超过最大限制,不能进行查询");
public static String escapeOrderBySql(String value) {
if (StrUtil.isNotEmpty(value)) {
if (!isValidOrderBySql(value)) {
throw new IllegalArgumentException("参数不符合规范,不能进行查询");
}
if (value.length() > ORDER_BY_MAX_LENGTH) {
throw new IllegalArgumentException("参数已超过最大限制,不能进行查询");
}
}
return value;
}
@@ -45,27 +42,16 @@ public class SqlUtil
/**
* 验证 order by 语法是否符合规范
*/
public static boolean isValidOrderBySql(String value)
{
return value.matches(SQL_PATTERN);
public static boolean isValidOrderBySql(String value) {
return SQL_PATTERN.matcher(value).matches();
}
/**
* SQL关键字检查
*/
public static void filterKeyword(String value)
{
if (StrUtil.isEmpty(value))
{
return;
}
List<String> sqlKeywords = StrUtil.split(SQL_REGEX, "\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StrUtil.indexOfIgnoreCase(value, sqlKeyword) > -1)
{
throw new IllegalArgumentException("参数存在SQL注入风险");
}
public static void filterKeyword(String value) {
if (StrUtil.isNotEmpty(value) && SQL_KEYWORD_PATTERN.matcher(value).find()) {
throw new IllegalArgumentException("参数存在 SQL 注入风险");
}
}
}

View File

@@ -9,7 +9,7 @@ import lombok.Getter;
@Getter
public enum CzgPayEnum {
SCANPAY("/api/open/payment/scanpay", "PC扫码支付"),
MICROPAY("/api/open/payment/micropay", "聚合反扫B扫C"),
MICROPAY("/api/open/payment/micropay", "聚合反扫B扫C/ 快捷收款"),
JSPAY("/api/open/payment/jspay", "公众号/生活号/银联js支付"),
LTPAY("/api/open/payment/ltpay", "小程序支付"),
H5PAY("/api/open/payment/h5pay", "手机网页支付"),

View File

@@ -2,7 +2,6 @@ package com.czg.service.product.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.core.page.PageQuery;
import com.czg.enums.StatusEnum;
import com.czg.enums.YesNoEnum;
import com.czg.exception.CzgException;
@@ -45,7 +44,7 @@ public class ShopProdUnitServiceImpl extends ServiceImpl<ShopProdUnitMapper, Sho
@Override
public Page<ShopProdUnitDTO> page(ShopProdUnitDTO param) {
QueryWrapper queryWrapper = buildQueryWrapper(param);
return super.pageAs(PageQuery.build(), queryWrapper, ShopProdUnitDTO.class);
return super.pageAs(PageUtil.buildPage(), queryWrapper, ShopProdUnitDTO.class);
}
@Override

View File

@@ -23,7 +23,7 @@ import java.util.List;
* @author mac
* @since 2025-02-07
*/
@DubboService(interfaceClass = SysParamsService.class)
@DubboService
@CacheConfig(cacheNames = "params")
public class SysParamsServiceImpl extends ServiceImpl<SysParamsMapper, SysParams> implements SysParamsService {