总体思路是增加一个注解类,将注解加到要进行记录变化的Java类属性上却可。
上代码:
1. 实现注解类:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {String value();boolean isIgnoreNull() default false;
}
2. 将注解加到Java类属性
@FieldName("产品编码")
private String productNo;
3. 写一个LogUtil类,对新旧对象进行比较,将变化的内容记录下来,返回List<String>,为了防止异常出现影响正常的业务,用try-catch进行异常处理
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;import **.FieldName;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;@Slf4j
public class LogUtil {private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");/*** 记录修改信息* @param newObj 更新后数据* @param oldObj 更新前数据* @param clazz* @return*/public static List<String> getUpdateContentList(Object newObj, Object oldObj, Class clazz) {List<String> contentList = new ArrayList<>();if (newObj == null || oldObj == null) {return contentList;}try {//通过hutool BeanUtil工具将实体类转换为MapMap newMap = BeanUtil.beanToMap(newObj);Map oldMap = BeanUtil.beanToMap(oldObj);//通过类对象获取类字段Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {//判断是否有FieldName注解if (field.isAnnotationPresent(FieldName.class)) {FieldName fieldName = field.getAnnotation(FieldName.class);//空的和忽略的字段不进行处理if (fieldName.isIgnoreNull() && ObjectUtil.isEmpty(newMap.get(field.getName()))) {continue;}String newValue = newMap.get(field.getName()) == null ? "" : newMap.get(field.getName()).toString();String oldValue = oldMap.get(field.getName()) == null ? "" : oldMap.get(field.getName()).toString();if(field.getType() == Date.class){try{if(StringUtils.isNotEmpty(newValue)){newValue = formatter.format(newMap.get(field.getName()));}if(StringUtils.isNotEmpty(oldValue)){oldValue = formatter.format(oldMap.get(field.getName()));}}catch (Exception e){e.printStackTrace();}}String changeField;Map<String, String> conMap = new HashMap<>();//新旧记录内容不同,说明是修改过,因此记录起来if (!newValue.equals(oldValue)) {//CHANGE_TEXT 自定义拼接内容//CHANGE_TEXT = "fieldName-oldValue --> 调整为 --> fieldName-newValue"String CHANGE_TEXT = "fieldName:oldValue --> newValue";changeField = CHANGE_TEXT.replaceAll("fieldName", fieldName.value()).replaceAll("oldValue", oldValue).replaceAll("newValue", newValue);log.info(changeField);contentList.add(changeField);}}}}catch (Exception e){e.printStackTrace();}return contentList;}
}
LogUtil用到的依赖是:
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.12</version>
</dependency>
一切准备就结果,接下来就是具体使用:
在Controller类的edit请求中:
// 某个Controller的edit方法中
List<String> updateContentList = getUpdateContentList(product);
String updateContent = "修改产品";
if(!updateContentList.isEmpty()){updateContent += ": "+updateContentList;
}
// 日志记录的service类新建一条更新日志
updateRecordService.setProductUpdateRecord(product.getId(), "编辑", updateContent);/*** 获取编辑前后的变化内容
*/private List<String> getUpdateContentList(Product product){Product oldObject = productService.getById(product.getId());return LogUtil.getUpdateContentList(product, oldObject, Product .class);
}
最后的效果如图: