package com.jieshun.jsis.utils;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
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.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.jieshun.core.security.common.context.BaseContextHandler;
import com.jieshun.jsis.annotation.OperateLog;
import com.jieshun.jsis.entity.operation.Log;
import com.jieshun.jsis.service.operation.LogService;
import lombok.extern.slf4j.Slf4j;
/**
* 系统操作日志切面
* */
@Aspect
@Component
@Slf4j
public class OperateLogAspect {
@Resource
private LogService logService;
/**
* 定义切面
* */
@Pointcut("@annotation(com.jieshun.jsis.annotation.OperateLog)")
public void cutOperate() {}
@Around(value="cutOperate()")
public Object around(ProceedingJoinPoint point) throws Throwable{
Object obj = null;
Signature sig = point.getSignature();
if(!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能在方法上使用");
}
MethodSignature msig = (MethodSignature)sig;
Method method = null;
try {
method = point.getTarget().getClass().getMethod(msig.getName(), msig.getParameterTypes());
}catch(NoSuchMethodException e) {
log.error(e.getMessage());
}
if(method != null) {
if(method.isAnnotationPresent(OperateLog.class)) {
log.info("aspect method={}",method.getName());
OperateLog annotation = method.getAnnotation(OperateLog.class);
Log operateLog = new Log();
operateLog.setFuncName(annotation.funcName());
operateLog.setOperateContent(annotation.operateContent());
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
operateLog.setOperateIp(getIRealIPAddr(request));
operateLog.setOperateTime(new Date());
operateLog.setOperateType(annotation.operateType().getCode());
String userName = StringUtils.isEmpty(BaseContextHandler.getUsername())?BaseContextHandler.getName():BaseContextHandler.getUsername();
if(StringUtils.isEmpty(userName)) {
Object[] args = point.getArgs();
if(args != null && args.length > 0 && args[0] instanceof Map<?,?>) {
//处理用户登录时的获取用户名的问题
try {
Map<String,Object> reqParam = (Map<String,Object>)args[0];
userName = reqParam.get("username").toString();
}catch(Exception e1) {
log.error(e1.getMessage());
}
}else {
log.error("无法获取到用户名");
}
}
operateLog.setOperator(userName);
operateLog.setSubFuncNodes(annotation.subFuncNodes());
try {
obj = point.proceed();
operateLog.setOperateContent(operateLog.getOperateContent()+",执行成功");
logService.insertSelective(operateLog);
}catch(Throwable e) {
operateLog.setOperateContent(operateLog.getOperateContent()+",执行失败");
logService.insertSelective(operateLog);
}
}else {
obj = point.proceed();
}
}else {
obj = point.proceed();
}
return obj;
}
/**
* 获取客户端真实IP
* */
private String getIRealIPAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
利用@Aspect声明一个切面。