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())) .serializeKeysWith(org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
// 设置值的序列化方式,使用 Fastjson2 序列化 // 设置值的序列化方式,使用 Fastjson2 序列化
.serializeValuesWith(org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair.fromSerializer(fastJson2RedisSerializer)) .serializeValuesWith(org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair.fromSerializer(fastJson2RedisSerializer))
// 设置缓存过期时间为 30 分钟 // 设置缓存过期时间为 120 分钟
.entryTtl(Duration.ofMinutes(30)); .entryTtl(Duration.ofMinutes(120));
// 创建 Redis 缓存管理器 // 创建 Redis 缓存管理器
return RedisCacheManager.builder(redisConnectionFactory) return RedisCacheManager.builder(redisConnectionFactory)

View File

@@ -41,7 +41,7 @@ public class CzgControllerAdvice {
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
public CzgResult<Object> notLoginErrorHandler(NotLoginException ex) { public CzgResult<Object> notLoginErrorHandler(NotLoginException ex) {
setErrorLog(ex); setErrorLog(ex);
return CzgResult.failure(CzgRespCode.NOT_LOGIN); return CzgResult.failure(CzgRespCode.NOT_LOGIN + ":" + ex.getMessage());
} }
@ResponseBody @ResponseBody
@@ -90,12 +90,13 @@ public class CzgControllerAdvice {
* 处理Hutool的校验工具类抛出异常 * 处理Hutool的校验工具类抛出异常
*/ */
@ExceptionHandler(ValidateException.class) @ExceptionHandler(ValidateException.class)
public CzgResult<Object> handleHutoolValidateException(ValidateException ex) { public CzgResult<Object> handleValidateException(ValidateException ex) {
return CzgResult.failure(CzgRespCode.PARAM_ERROR.getCode(), ex.getMessage()); return CzgResult.failure(CzgRespCode.PARAM_ERROR.getCode(), ex.getMessage());
} }
@ExceptionHandler(DuplicateKeyException.class) @ExceptionHandler(DuplicateKeyException.class)
public CzgResult handleDuplicateKeyException(DuplicateKeyException ex) { public CzgResult<Object> handleDuplicateKeyException(DuplicateKeyException ex) {
setErrorLog(ex);
return CzgResult.failure(CzgRespCode.RECORD_EXISTED); 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; package com.czg.utils;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
@@ -19,53 +17,123 @@ import java.util.Map;
*/ */
public class AssertUtil { public class AssertUtil {
/**
* 检查字符串是否不为空或空白字符,如果为空或空白字符则抛出异常
*
* @param str 要检查的字符串
* @param msg 异常信息
* @throws ValidateException 如果字符串为空或空白字符
*/
public static void isBlank(String str, String msg) { public static void isBlank(String str, String msg) {
if (StrUtil.isBlank(str)) { if (StrUtil.isBlank(str)) {
throw new ValidateException(msg); throw new ValidateException(msg);
} }
} }
/**
* 检查字符串是否不为空或空白字符,如果为空或空白字符则抛出异常
*
* @param str 要检查的字符串
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果字符串为空或空白字符
*/
public static void isBlank(String str, String errorMsgTemplate, Object... params) { public static void isBlank(String str, String errorMsgTemplate, Object... params) {
isBlank(str, StrUtil.format(errorMsgTemplate, params)); isBlank(str, StrUtil.format(errorMsgTemplate, params));
} }
/**
* 检查对象是否不为 null如果为 null 则抛出异常
*
* @param object 要检查的对象
* @param msg 异常信息
* @throws ValidateException 如果对象为 null
*/
public static void isNull(Object object, String msg) { public static void isNull(Object object, String msg) {
if (object == null) { if (object == null) {
throw new ValidateException(msg); 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) { public static void isNull(Object object, String errorMsgTemplate, Object... params) {
isNull(object, StrUtil.format(errorMsgTemplate, params)); isNull(object, StrUtil.format(errorMsgTemplate, params));
} }
/**
* 检查数组是否不为空,如果为空则抛出异常
*
* @param array 要检查的数组
* @param msg 异常信息
* @throws ValidateException 如果数组为空
*/
public static void isArrayEmpty(Object[] array, String msg) { public static void isArrayEmpty(Object[] array, String msg) {
if (ArrayUtil.isEmpty(array)) { if (ArrayUtil.isEmpty(array)) {
throw new ValidateException(msg); throw new ValidateException(msg);
} }
} }
/**
* 检查数组是否不为空,如果为空则抛出异常
*
* @param array 要检查的数组
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果数组为空
*/
public static void isArrayEmpty(Object[] array, String errorMsgTemplate, Object... params) { public static void isArrayEmpty(Object[] array, String errorMsgTemplate, Object... params) {
isArrayEmpty(array, StrUtil.format(errorMsgTemplate, params)); isArrayEmpty(array, StrUtil.format(errorMsgTemplate, params));
} }
/**
* 检查列表是否不为空,如果为空则抛出异常
*
* @param list 要检查的列表
* @param msg 异常信息
* @throws ValidateException 如果列表为空
*/
public static void isListEmpty(List<?> list, String msg) { public static void isListEmpty(List<?> list, String msg) {
if (CollUtil.isEmpty(list)) { if (CollUtil.isEmpty(list)) {
throw new ValidateException(msg); throw new ValidateException(msg);
} }
} }
/**
* 检查列表是否不为空,如果为空则抛出异常
*
* @param list 要检查的列表
* @param errorMsgTemplate 异常信息模板
* @param params 异常信息模板的参数
* @throws ValidateException 如果列表为空
*/
public static void isListEmpty(List<?> list, String errorMsgTemplate, Object... params) { public static void isListEmpty(List<?> list, String errorMsgTemplate, Object... params) {
isListEmpty(list, StrUtil.format(errorMsgTemplate, 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)) { if (MapUtil.isEmpty(map)) {
throw new ValidateException(msg); 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)); isMapEmpty(map, StrUtil.format(errorMsgTemplate, params));
} }
} }

View File

@@ -1,29 +1,104 @@
package com.czg.utils; package com.czg.utils;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.czg.core.page.PageDomain; 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 com.mybatisflex.core.query.QueryWrapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
/** /**
* 分页工具类 * 分页工具类
*
* @author tankaikai * @author tankaikai
* @since 2025-02-11 16:56 * @since 2025-02-11 16:56
*/ */
@UtilityClass @UtilityClass
public class PageUtil { 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 * @return QueryWrapper
*/ */
public QueryWrapper buildPageQueryWrapper(){ public static QueryWrapper buildPageQueryWrapper() {
QueryWrapper queryWrapper = QueryWrapper.create(); QueryWrapper queryWrapper = QueryWrapper.create();
PageDomain pageDomain = TableSupport.buildPageRequest(); PageDomain pageDomain = buildPageAndSortRequest();
if (StrUtil.isNotEmpty(pageDomain.getOrderBy())) { if (StrUtil.isNotEmpty(pageDomain.getOrderBy())) {
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
queryWrapper.orderBy(orderBy); queryWrapper.orderBy(orderBy);
} }
return queryWrapper; 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; package com.czg.utils;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import java.util.regex.Pattern;
import java.util.List;
/** /**
* sql操作工具类 * sql操作工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class SqlUtil public class SqlUtil {
{
/** /**
* 定义常用的 sql关键字 * 定义常用的 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最大长度 * 限制orderBy最大长度
@@ -29,15 +27,14 @@ public class SqlUtil
/** /**
* 检查字符,防止注入绕过 * 检查字符,防止注入绕过
*/ */
public static String escapeOrderBySql(String value) public static String escapeOrderBySql(String value) {
{ if (StrUtil.isNotEmpty(value)) {
if (StrUtil.isNotEmpty(value) && !isValidOrderBySql(value)) if (!isValidOrderBySql(value)) {
{ throw new IllegalArgumentException("参数不符合规范,不能进行查询");
throw new IllegalArgumentException("参数不符合规范,不能进行查询"); }
} if (value.length() > ORDER_BY_MAX_LENGTH) {
if (StrUtil.length(value) > ORDER_BY_MAX_LENGTH) throw new IllegalArgumentException("参数已超过最大限制,不能进行查询");
{ }
throw new IllegalArgumentException("参数已超过最大限制,不能进行查询");
} }
return value; return value;
} }
@@ -45,27 +42,16 @@ public class SqlUtil
/** /**
* 验证 order by 语法是否符合规范 * 验证 order by 语法是否符合规范
*/ */
public static boolean isValidOrderBySql(String value) public static boolean isValidOrderBySql(String value) {
{ return SQL_PATTERN.matcher(value).matches();
return value.matches(SQL_PATTERN);
} }
/** /**
* SQL关键字检查 * SQL关键字检查
*/ */
public static void filterKeyword(String value) public static void filterKeyword(String value) {
{ if (StrUtil.isNotEmpty(value) && SQL_KEYWORD_PATTERN.matcher(value).find()) {
if (StrUtil.isEmpty(value)) throw new IllegalArgumentException("参数存在 SQL 注入风险");
{
return;
}
List<String> sqlKeywords = StrUtil.split(SQL_REGEX, "\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StrUtil.indexOfIgnoreCase(value, sqlKeyword) > -1)
{
throw new IllegalArgumentException("参数存在SQL注入风险");
}
} }
} }
} }

View File

@@ -9,7 +9,7 @@ import lombok.Getter;
@Getter @Getter
public enum CzgPayEnum { public enum CzgPayEnum {
SCANPAY("/api/open/payment/scanpay", "PC扫码支付"), 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支付"), JSPAY("/api/open/payment/jspay", "公众号/生活号/银联js支付"),
LTPAY("/api/open/payment/ltpay", "小程序支付"), LTPAY("/api/open/payment/ltpay", "小程序支付"),
H5PAY("/api/open/payment/h5pay", "手机网页支付"), 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.bean.BeanUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.czg.core.page.PageQuery;
import com.czg.enums.StatusEnum; import com.czg.enums.StatusEnum;
import com.czg.enums.YesNoEnum; import com.czg.enums.YesNoEnum;
import com.czg.exception.CzgException; import com.czg.exception.CzgException;
@@ -45,7 +44,7 @@ public class ShopProdUnitServiceImpl extends ServiceImpl<ShopProdUnitMapper, Sho
@Override @Override
public Page<ShopProdUnitDTO> page(ShopProdUnitDTO param) { public Page<ShopProdUnitDTO> page(ShopProdUnitDTO param) {
QueryWrapper queryWrapper = buildQueryWrapper(param); QueryWrapper queryWrapper = buildQueryWrapper(param);
return super.pageAs(PageQuery.build(), queryWrapper, ShopProdUnitDTO.class); return super.pageAs(PageUtil.buildPage(), queryWrapper, ShopProdUnitDTO.class);
} }
@Override @Override

View File

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