通过aop记录日志,记录修改前后的数据,精确到每个字段

package com.ak1ak1.common.shiro;

import java.lang.reflect.Field;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ak1ak1.annotation.PropertyName;
import com.ak1ak1.pojo.Record;
import com.ak1ak1.pojo.systemConfig.User;
import com.ak1ak1.service.IRecordService;


/**
 * @author hejie
 * @date 2019年9月20日
 * @desc 日志代理
 */
public class RecordProxy {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(RecordProxy.class);
    
    // 得到日志服务层对象
    private IRecordService recordService;
    // 获取当前session
    private Session session;
    
    public RecordProxy(){}
    
    public RecordProxy(IRecordService recordService,Session session){
        this.recordService = recordService;
        this.session = session;
    }
    
    /**
     * @param oldObj 原数据对象
     * @param newObj 修改后数据对象
     */
    public void addRecord(Object oldObj, Object newObj){
        // 获取到当前用户
        User user = com.alibaba.fastjson.JSON.parseObject(session.getAttribute("User").toString(), User.class);
        try {
            // 得到类对象
            Class<? extends Object> class1 = oldObj.getClass();
            Class<? extends Object> class2 = newObj.getClass();
            if(!class1.equals(class2)){
                throw new RuntimeException("请传入两个相同的实体类对象");
            }
            // 得到属性集合
            Field[] fields1 = class1.getDeclaredFields();
            Field[] fields2 = class2.getDeclaredFields();
            PropertyName model = class1.getAnnotation(PropertyName.class);
            int modelId = model.modelId();
            StringBuffer info = new StringBuffer();
            Integer id = null;
            for (Field field1 : fields1) {
                field1.setAccessible(true);    // 设置属性是可以访问的(私有的也可以)
                if(id == null && field1.getName().equals("id")){
                    id = (Integer)field1.get(oldObj);
                }
                for (Field field2 : fields2) {
                    field2.setAccessible(true);    // 设置属性是可以访问的(私有的也可以)
                    if(field1.equals(field2)){    // 比较属性名是否一样
                        if(field2.get(newObj) == null || StringUtils.isEmpty(field2.get(newObj) + "")){
                            break;    // 属性名称一样就退出二级循环
                        }
                        System.out.println(field1.get(oldObj));
                        System.out.println(field2.get(newObj));
                        if(!field1.get(oldObj).equals(field2.get(newObj))){    // 比较属性值是否一样
                            // 得到注解
                            PropertyName pn = field1.getAnnotation(PropertyName.class);
                            if(pn != null){
                                info.append(pn.value() + ":"" +  field1.get(oldObj) + "" 改成 "" + field2.get(newObj) + "",");
                            }
                        }
                        break;    // 属性名称一样就退出二级循环
                    }
                }
            }
            if(info.length() != 0){
                // 设置日志信息
                Record record = new Record();
                record.setUserID(user.getUserID() + "");
                record.setUserName(user.getUserName());
                record.setCreateDate(new Date());
                record.setRemark(info.length() == 0 ? info.toString() : info.substring(0, info.length() - 1));
                record.setType(modelId);            
                record.setMachineIP(session.getHost());
                record.setModelId(id);
                recordService.addRecord(record);
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("属性内容更改前后验证错误,日志无法被记录!");
        }
    }
    
}
原文地址:https://www.cnblogs.com/hjieone/p/11586252.html