1.DateUtils提升parseDateToStr性能与安全性

2.ExceptionUtil使用try-with-resources关闭需要关闭的流
3.解决使用@Excel字典值属性时,导入导出功能中当用户上送字典值会导致使用该字典值的字段设置不了希望设置的值
pull/504/head
MagicJson 2024-07-12 15:28:03 +08:00
parent 5bef005075
commit fff78232a2
3 changed files with 155 additions and 88 deletions

View File

@ -1,38 +1,40 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.*;
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date; import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils; import java.util.concurrent.ConcurrentHashMap;
/** /**
* *
* *
* @author ruoyi * @author ruoyi
*/ */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils public final class DateUtils extends org.apache.commons.lang3.time.DateUtils
{ {
public static String YYYY = "yyyy";
public static String YYYY_MM = "yyyy-MM"; public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYY_MM_DD = "yyyy-MM-dd"; public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = { private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/**
* 线 Map DateTimeFormatter
* 使
*/
private static final ConcurrentHashMap<String, DateTimeFormatter> datetimeFormatterMap = new ConcurrentHashMap<>();
/** /**
* Date * Date
* *
@ -53,32 +55,64 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return dateTimeNow(YYYY_MM_DD); return dateTimeNow(YYYY_MM_DD);
} }
public static final String getTime() public static String getTime()
{ {
return dateTimeNow(YYYY_MM_DD_HH_MM_SS); return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
} }
public static final String dateTimeNow() public static String dateTimeNow()
{ {
return dateTimeNow(YYYYMMDDHHMMSS); return dateTimeNow(YYYYMMDDHHMMSS);
} }
public static final String dateTimeNow(final String format) public static String dateTimeNow(final String format)
{ {
return parseDateToStr(format, new Date()); return parseDateToStr(format, new Date());
} }
public static final String dateTime(final Date date) public static String dateTime(final Date date)
{ {
return parseDateToStr(YYYY_MM_DD, date); return parseDateToStr(YYYY_MM_DD, date);
} }
/**
public static final String parseDateToStr(final String format, final Date date) * java.util.Date
{ *
return new SimpleDateFormat(format).format(date); * @param format
* @param date java.util.Date
* @return
*/
public static String parseDateToStr(final String format, final Date date){
return toLocalDateTime(date).format(getDateTimeFormatter(format));
} }
public static final Date dateTime(final String format, final String ts) /**
* java.util.Date java.time.LocalDateTime
*
* @param date java.util.Date
* @return java.time.LocalDateTime
*/
public static LocalDateTime toLocalDateTime(Date date) {
// 将 java.util.Date 对象转换为 java.time.Instant 对象
return date.toInstant()
// 将 Instant 对象转化为带有时区信息的 ZonedDateTime 对象,时区使用系统默认时区
.atZone(ZoneId.systemDefault())
// 将 ZonedDateTime 对象转换为 LocalDateTime 对象
.toLocalDateTime();
}
/**
* DateTimeFormatter
* DateTimeFormatter
*
* @param format
* @return DateTimeFormatter
*/
public static DateTimeFormatter getDateTimeFormatter(String format){
return datetimeFormatterMap.computeIfAbsent(format, DateTimeFormatter::ofPattern);
}
public static Date dateTime(final String format, final String ts)
{ {
try try
{ {
@ -93,7 +127,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
/** /**
* // 2018/08/08 * // 2018/08/08
*/ */
public static final String datePath() public static String datePath()
{ {
Date now = new Date(); Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd"); return DateFormatUtils.format(now, "yyyy/MM/dd");
@ -102,7 +136,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
/** /**
* // 20180808 * // 20180808
*/ */
public static final String dateTime() public static String dateTime()
{ {
Date now = new Date(); Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd"); return DateFormatUtils.format(now, "yyyyMMdd");

View File

@ -1,9 +1,14 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.util.List;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* *
@ -17,7 +22,8 @@ public class DictUtils
* *
*/ */
public static final String SEPARATOR = ","; public static final String SEPARATOR = ",";
public static final String DICT_LABEL = "dictLabel";
public static final String DICT_VALUE = "dictValue";
/** /**
* *
* *
@ -79,7 +85,7 @@ public class DictUtils
/** /**
* *
* *
* @param dictType * @param dictType
* @param dictValue * @param dictValue
* @param separator * @param separator
@ -87,37 +93,7 @@ public class DictUtils
*/ */
public static String getDictLabel(String dictType, String dictValue, String separator) public static String getDictLabel(String dictType, String dictValue, String separator)
{ {
StringBuilder propertyString = new StringBuilder(); return getDictElement(dictType, dictValue, separator, DICT_LABEL);
List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.isNull(datas))
{
return StringUtils.EMPTY;
}
if (StringUtils.containsAny(dictValue, separator))
{
for (SysDictData dict : datas)
{
for (String value : dictValue.split(separator))
{
if (value.equals(dict.getDictValue()))
{
propertyString.append(dict.getDictLabel()).append(separator);
break;
}
}
}
}
else
{
for (SysDictData dict : datas)
{
if (dictValue.equals(dict.getDictValue()))
{
return dict.getDictLabel();
}
}
}
return StringUtils.stripEnd(propertyString.toString(), separator);
} }
/** /**
@ -130,37 +106,89 @@ public class DictUtils
*/ */
public static String getDictValue(String dictType, String dictLabel, String separator) public static String getDictValue(String dictType, String dictLabel, String separator)
{ {
StringBuilder propertyString = new StringBuilder(); return getDictElement(dictType, dictLabel, separator,DICT_VALUE);
List<SysDictData> datas = getDictCache(dictType); }
if (StringUtils.isNull(datas))
{
/**
*
*
* @param dictType
* @param dictCondition
* @param separator
* @return
*/
public static String getDictElement(String dictType, String dictCondition
, String separator, String filedAttr) {
// 获取字典缓存
List<SysDictData> dictData = getDictCache(dictType);
if (StringUtils.isNull(dictData)) {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }
if (StringUtils.containsAny(dictLabel, separator)) // 处理单个标签的情况
{ if (!StringUtils.containsAny(dictCondition, separator)) {
for (SysDictData dict : datas) return getSingleDictElement(dictData, dictCondition, filedAttr);
{ }
for (String label : dictLabel.split(separator)) // 处理多个标签的情况
{ return getMultipleDictElements(dictData, dictCondition, separator, filedAttr);
if (label.equals(dict.getDictLabel())) }
{ /**
propertyString.append(dict.getDictValue()).append(separator); *
break; *
} * @param dictData
} * @param dictCondition
* @param dictAttr
* @return
*/
private static String getDictElement(List<SysDictData> dictData, String dictCondition, String dictAttr) {
// 遍历字典数据
for (SysDictData dict : dictData) {
// 判断需要转换的字典属性是DICT_LABEL还是DICT_VALUE
String dictTransV = Objects.equals(DICT_LABEL, dictAttr) ? DICT_VALUE : DICT_LABEL;
// 获取转换后的字典属性值
String retValue = ReflectUtils.invokeGetter(dict, dictTransV);
// 如果转换后的值和条件值相等,则返回所需的字典属性值
if (Objects.equals(dictCondition, retValue)) {
return ReflectUtils.invokeGetter(dict, dictAttr);
} }
} }
else return StringUtils.EMPTY; // 没有找到匹配的标签,返回空字符串
{ }
for (SysDictData dict : datas)
{ /**
if (dictLabel.equals(dict.getDictLabel())) *
{ *
return dict.getDictValue(); * @param dictData
} * @param dictCondition
} * @param dictAttr
* @return
*/
private static String getSingleDictElement(List<SysDictData> dictData, String dictCondition, String dictAttr) {
// 如果字典属性是DICT_VALUE并且条件是数字则直接返回条件
if (Objects.equals(DICT_VALUE, dictAttr) && StringUtils.isNumeric(dictCondition)) {
return dictCondition;
} }
return StringUtils.stripEnd(propertyString.toString(), separator); return getDictElement(dictData, dictCondition, dictAttr);
}
/**
*
*
* @param dictData
* @param dictCondition
* @param separator
* @param dictAttr
* @return
*/
private static String getMultipleDictElements(List<SysDictData> dictData, String dictCondition, String separator, String dictAttr) {
// 分割条件值,得到多个条件
String[] conditions = dictCondition.split(separator);
// 使用Stream处理多个条件
return Stream.of(conditions)
.map(condition -> getDictElement(dictData, condition, dictAttr))
.filter(StringUtils::isNotEmpty) // 过滤掉空值
.collect(Collectors.joining(separator)); // 拼接结果
} }
/** /**

View File

@ -1,8 +1,9 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import org.apache.commons.lang3.exception.ExceptionUtils;
/** /**
* *
@ -16,9 +17,13 @@ public class ExceptionUtil
*/ */
public static String getExceptionMessage(Throwable e) public static String getExceptionMessage(Throwable e)
{ {
// StringWriter#close()关闭是否都可以 但放入try-with-resources还需要处理抛出的IO异常
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true)); // PrintWriter#close()建议关闭 使用try-with-resources简洁关闭pw
return sw.toString(); try(PrintWriter pw = new PrintWriter(sw, true)){
e.printStackTrace(pw);
return sw.toString();
}
} }
public static String getRootErrorMessage(Exception e) public static String getRootErrorMessage(Exception e)