日志记录到redis展现形式
1.基于注解的方式实现日志记录,扫描对应的方法实现日志记录
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BussinessLog {
/**
* 业务的名称,例如:"修改菜单"
*/
String value() default "";
/**
* 被修改的实体的唯一标识,例如:菜单实体的唯一标识为"id"
*/
String key() default "id";
/**
* 业务类型
*/
String type() default "0";
/**
* 字典(用于查找key的中文名称和字段的中文名称)
*/
Class<? extends AbstractDictMap> dict() default SystemDict.class;
}
2.扫描的方法,基于注解实现方法扫描并且记录日志
3.基于@Aspect注解,实现日志扫描,并且记录日志
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 日志记录
*
*/
@Aspect
@Component
public class LogAop {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Pointcut(value = "@annotation(com.stylefeng.guns.core.common.annotion.BussinessLog)")
public void cutService() {
}
@Around("cutService()")
public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
//先执行业务
Object result = point.proceed();
try {
handle(point);
} catch (Exception e) {
log.error("日志记录出错!", e);
}
return result;
}
private void handle(ProceedingJoinPoint point) throws Exception {
//获取拦截的方法名
Signature sig = point.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Object target = point.getTarget();
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
String methodName = currentMethod.getName();
//如果当前用户未登录,不做日志
ShiroUser user = ShiroKit.getUser();
if (null == user) {
return;
}
//获取拦截方法的参数
String className = point.getTarget().getClass().getName();
Object[] params = point.getArgs();
//获取操作名称
BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class);
String bussinessName = annotation.value();
String key = annotation.key();
Class dictClass = annotation.dict();
StringBuilder sb = new StringBuilder();
for (Object param : params) {
sb.append(param);
sb.append(" & ");
}
//如果涉及到修改,比对变化
String msg;
if (bussinessName.contains("修改") || bussinessName.contains("编辑")) {
Object obj1 = LogObjectHolder.me().get();
Map<String, String> obj2 = HttpContext.getRequestParameters();
msg = Contrast.contrastObj(dictClass, key, obj1, obj2);
} else {
Map<String, String> parameters = HttpContext.getRequestParameters();
AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
msg = Contrast.parseMutiKey(dictMap, key, parameters);
}
log.info("[记录日志][RESULT:{}]",user.getId()+bussinessName+className+methodName+msg.toString());
LogManager.me().executeLog(LogTaskFactory.bussinessLog(user.getId(), bussinessName, className, methodName, msg));
}
}
4.比较两个对象的工具类
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
/**
* 对比两个对象的变化的工具类
*
* @author ...
* @Date 2017/3/31 10:36
*/
public class Contrast {
//记录每个修改字段的分隔符
public static final String separator = ";;;";
/**
* 比较两个对象,并返回不一致的信息
*
* @author ...
* @Date 2017/5/9 19:34
*/
public static String contrastObj(Object pojo1, Object pojo2) {
String str = "";
try {
Class clazz = pojo1.getClass();
Field[] fields = pojo1.getClass().getDeclaredFields();
int i = 1;
for (Field field : fields) {
if ("serialVersionUID".equals(field.getName())) {
continue;
}
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
Method getMethod = pd.getReadMethod();
Object o1 = getMethod.invoke(pojo1);
Object o2 = getMethod.invoke(pojo2);
if (o1 == null || o2 == null) {
continue;
}
if (o1 instanceof Date) {
o1 = DateUtil.getDay((Date) o1);