总体思路是增加一个注解类,将注解加到要进行记录变化的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工具将实体类转换为Map
Map 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);
}
最后的效果如图: