说明:这个工具类的编写目的是为了将JSON类型的字符串(redis缓存)转换为我项目中的实体类对象以便进行下一步处理。
因为在处理过程中出现了当缓存的时间类型为时间戳时无法转换为我的时间格式,所以进行了一些处理;
如果使用fastJson,可以忽略,fastJson不需要额外进行处理;
代码如下:
package com.tyls.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.SneakyThrows;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EntityStringUtil {
/**
* 将实体类对象转换为字符串
*
* @param entity 实体类对象
* @return 转换后的字符串
*/
public static String convertEntityToString(Object entity) {
return JSON.toJSONString(entity);
}
/**
* 转换JSON字符串为实体类对象
* @param jsonString JSON字符串
* @param clazz 实体类类型
* @return
* @param <T>
*/
@SneakyThrows
public static <T> T convertStringToEntity(String jsonString, Class<T> clazz) {
JSONObject jsonObject = JSONObject.parseObject(jsonString);
if(jsonObject == null) {
return null;
}
// 遍历实体类的所有字段,查找并处理标注了 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")的日期/时间字段
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if(isEntityClass(field.getType())){
Object nestedEntity = convertStringToEntity(jsonObject.getString(field.getName()), field.getType());
// 使用反射将子实体对象设置到当前字段
jsonObject.put(field.getName(), nestedEntity);
}else if (field.isAnnotationPresent(JsonFormat.class)) {
JsonFormat JsonFormat = field.getAnnotation(JsonFormat.class);
if ("yyyy-MM-dd HH:mm:ss".equals(JsonFormat.pattern())) { // 根据实际格式调整
String fieldName = field.getName();
if (jsonObject.containsKey(fieldName)) {
try {
String timestampStr = jsonObject.getString(fieldName);
if(StrUtil.isBlank(timestampStr)) continue;
long timestampMillis = Long.parseLong(timestampStr);
Instant instant = Instant.ofEpochMilli(timestampMillis);
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.systemDefault());
jsonObject.put(fieldName, localDateTime);
} catch (Exception e) {
// Handle parsing exceptions or log error
}
}
}
}
}
// 使用已更新的 JSONObject 转换为实体类
T entity = JSON.parseObject(jsonObject.toJSONString(), clazz);
//convertDateTimeFields(entity);
return entity;
}
/**
* 判断是否为实体类
* @param clazz
* @return
*/
private static boolean isEntityClass(Class<?> clazz) {
// 根据实际情况判断一个类是否为实体类
// 以下仅作为示例,您可以根据实际项目需求调整判断条件
return !Arrays.asList(
String.class,
Integer.class,
Long.class,
Double.class,
Float.class,
Boolean.class,
Enum.class,
BigDecimal.class,
LocalDateTime.class,
LocalDate.class
).contains(clazz) && !clazz.isPrimitive();
}
/**
* 将字符串转换为实体类对象列表
*
* @param jsonString 字符串
* @param clazz 实体类的Class对象
* @param <T> 实体类的类型
* @return 转换后的实体类对象列表
*/
public static <T> List<T> convertStrToEntityList(String jsonString, Class<T> clazz) {
if (jsonString == null || jsonString.isEmpty())
return null;
List<T> list = new ArrayList<>();
JSONArray jsonStrArray = JSON.parseArray(jsonString);
for (Object jsonObject : jsonStrArray) {
T jsonModel = JSONObject.parseObject(jsonObject.toString(), clazz);
list.add(jsonModel);
}
return list;
}
/**
* 将字符串列表转换为实体类集合
*
* @param jsonList 字符串列表
* @param clazz 实体类的Class对象
* @param <T> 实体类的类型
* @return 转换后的实体类集合
*/
public static <T> List<T> convertStrListToEntList(List<String> jsonList, Class<T> clazz) {
List<T> entityList = new ArrayList<>();
for (String jsonString : jsonList) {
T entity = convertStringToEntity(jsonString, clazz);
entityList.add(entity);
}
return entityList;
}
private static final String DATE_TIME_PATTERN = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}";
/**
* 检查字段类型是否为 LocalDateTime ,如果是字符串类型并匹配了日期时间模式,则将其转换为 LocalDateTime 对象。
*
* @param entity
*/
private static void convertDateTimeFields(Object entity) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
Pattern pattern = Pattern.compile(DATE_TIME_PATTERN);
Class<?> clazz = entity.getClass();
for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
if (field.getType().equals(LocalDateTime.class)) {
field.setAccessible(true);
try {
Object value = field.get(entity);
if (value instanceof String) {
String dateTimeString = (String) value;
Matcher matcher = pattern.matcher(dateTimeString);
if (matcher.find()) {
LocalDateTime dateTime = LocalDateTime.parse(matcher.group(), formatter);
field.set(entity, dateTime);
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
我的项目中,所有需要处理的时间均被
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
注解所覆盖,故此没有做其他的适配,使用时可以根据自己的项目情况分析判断,更改匹配逻辑。
菜鸟思路创解,如有更好的思路或认为改代码有错误,欢迎评论指正。