添加操作日志
package com.sugon.cloudview.cloudview.aspect;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.sugon.cloudview.cloudview.bo.log.Log;
import com.sugon.cloudview.cloudview.exception.ApiException;
import com.sugon.cloudview.cloudview.framework.rest.ApiHelper;
import com.sugon.cloudview.cloudview.user.bo.Role;
import com.sugon.cloudview.cloudview.user.bo.User;
@Aspect
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
// @Autowired
// private LogFeign logApi;
@Value("${cloudview.log.url}")
private String logUrl;
@Pointcut("@annotation(com.sugon.cloudview.cloudview.aspect.LogRecord)")
public void logPointcut() {
}
/**
* 拦截器具体实现
*
* @param pjp
* @return JsonResult(被拦截方法的执行结果,或需要登录的错误提示。)
*/
@Around("logPointcut() @annotation(LogRecord))")
public Object Interceptor(ProceedingJoinPoint joinPoint) {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
Object result = null;
try {
// 获取用户信息
User u = (User) SecurityUtils.getSubject().getPrincipal();
result = joinPoint.proceed();
String targetName = joinPoint.getTarget().getClass().getName();// 获取目标类的包名+类名
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
if ("login".equals(methodName) && !(result.toString().contains("\"returnCode\":100"))) {// 用户登录失败
JSONObject loginArgs = JSON.parseObject(arguments[0].toString());
u = new User();
u.setUsername((String) loginArgs.get("username"));
}
Class targetClass = Class.forName(targetName);
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
// 这样获取的是更改前方法上的注解值 Method
// realMethod=joinPoint.getTarget().getClass().getDeclaredMethod(methodName,method.getParameterTypes());
Method realMethod = targetClass.getMethod(methodName, method.getParameterTypes());
// 获取的注解值不是最新的
// Method realMethod2 = targetClass.getDeclaredMethod(methodName,
// method.getParameterTypes());
LogRecord logRecord = realMethod.getDeclaredAnnotation(LogRecord.class);
boolean contains = false;// 方法调用成功标志
if ((result == null && methodName.contains("export")) || result.toString().contains("\"returnCode\":100")) {// 导出方法没有返回值
contains = true;
}
if (null != logRecord) {// 访问成功
Log log = new Log();
if (u.getRoles() != null) {
Role role = u.getRoles().get(0);
log.setRoleCode(role.getRoleCode());
}
log.setOperaterName(u.getUsername());
log.setOperaterId(u.getId());
// 获取ip
String ipAddress = getIpAddress(request);
log.setOperaterIp(ipAddress);
// 方法体上传过来的参数
log.setOperateName(logRecord.operateName());
log.setEventCategory(logRecord.eventCategory());
log.setRiskLevel(logRecord.riskLevel());
log.setRequestType(logRecord.requestType());
log.setTargetType(logRecord.targetType());
log.setDatacenterName(logRecord.datacenterName());
String detail = "";
String operateStatus = "成功";
String actionType = "一般行为";
if (contains) {
detail = log.getOperateName() + " 操作成功";
} else {// 访问失败
Gson gson = new Gson();
JSONObject parseObject = JSON.parseObject((String) result);
Object object = parseObject.get("returnMsg");
operateStatus = "失败";
actionType = "异常行为";
detail = log.getOperateName() + " 失败, 请求方法是:" + targetName + "." + methodName + "请求参数是:[ " + arguments + " ]失败原因:" + object;
if (object instanceof String) {
String returnMsgStr = (String) object;
if (returnMsgStr.contains("authorization")) {
actionType = "违规行为";
}
}
}
log.setActionType(actionType);
log.setOperateStatus(operateStatus);
log.setDetail(detail);
// logApi.createLog(log);
// 创建日志
Map
dataMap.put("requestType", log.getRequestType());
dataMap.put("operateName", log.getOperateName());
dataMap.put("targetType", log.getTargetType());
dataMap.put("operateStatus", log.getOperateStatus());
dataMap.put("operaterId", log.getOperaterId());
dataMap.put("operaterName", log.getOperaterName());
dataMap.put("operaterIp", log.getOperaterIp());
dataMap.put("eventCategory", log.getEventCategory());
dataMap.put("riskLevel", log.getRiskLevel());
dataMap.put("actionType", log.getActionType());
dataMap.put("roleCode", log.getRoleCode());
dataMap.put("detail", log.getDetail());
ApiHelper.doPost(logUrl + "/rest/logRest/add", dataMap);
}
} catch (Throwable e) {
e.printStackTrace();
logger.error("exception: ", e);
result = new ApiException("日志接口异常", e);
} finally {
return result;
}
}
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {// localhost
ip = "127.0.0.1";
}
return ip;
}
}
//动态改变注解的内容
package com.sugon.cloudview.cloudview.base.utils;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import com.sugon.cloudview.cloudview.aspect.LogRecord;
public class AnnotationUtil {
public static void setValue(Class targetClass, String methodName, String fieldName, String updatedName) {
try {
Method[] methods = targetClass.getMethods();
if (methods != null) {
for (Method method : methods) {
// 获取同名的方法,有bug,一个类中有同名的方法会发生问题,所以编码的时候注意
if (method.getName().equals(methodName)) {
// 获取val字段上的Foo注解实例
LogRecord logRecord = method.getAnnotation(LogRecord.class);
// 获取 foo 这个代理实例所持有的 InvocationHandler
InvocationHandler h = Proxy.getInvocationHandler(logRecord);
// 获取 AnnotationInvocationHandler 的 memberValues 字段
Field hField = h.getClass().getDeclaredField("memberValues");
// 因为这个字段事 private final 修饰,所以要打开权限
hField.setAccessible(true);
// 获取 memberValues
Map memberValues = (Map) hField.get(h);
// 修改 value 属性值
memberValues.put(fieldName, updatedName);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}