package com.huaheng.framework.aspectj; import java.lang.reflect.Method; import java.util.Map; import com.huaheng.common.utils.AddressUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; 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.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSONObject; import com.huaheng.common.utils.ServletUtils; import com.huaheng.common.utils.StringUtils; import com.huaheng.common.utils.security.ShiroUtils; import com.huaheng.framework.aspectj.lang.annotation.Log; import com.huaheng.framework.aspectj.lang.constant.BusinessStatus; import com.huaheng.pc.monitor.operlog.domain.OperLog; import com.huaheng.pc.monitor.operlog.service.IOperLogService; import com.huaheng.pc.system.user.domain.User; import javax.servlet.http.HttpServletRequest; /** * 操作日志记录处理 * * @author huaheng */ @Aspect @Component @EnableAsync public class LogAspect { private static final Logger log = LoggerFactory.getLogger(LogAspect.class); @Autowired private IOperLogService operLogService; // 配置织入点 @Pointcut("@annotation(com.huaheng.framework.aspectj.lang.annotation.Log)") public void logPointCut() { } /** * 前置通知 用于拦截操作 * * @param joinPoint 切点 */ @AfterReturning(pointcut = "logPointCut()") public void doBefore(JoinPoint joinPoint) { handleLog(joinPoint, null); } /** * 拦截异常操作 * * @param joinPoint * @param e */ @AfterThrowing(value = "logPointCut()", throwing = "e") public void doAfter(JoinPoint joinPoint, Exception e) { handleLog(joinPoint, e); } @Async protected void handleLog(final JoinPoint joinPoint, final Exception e) { try { // 获得注解 Log controllerLog = getAnnotationLog(joinPoint); if (controllerLog == null) { return; } // 获取当前的用户 User currentUser = ShiroUtils.getUser(); // *========数据库日志=========*// OperLog operLog = new OperLog(); operLog.setStatus(BusinessStatus.SUCCESS); // 请求的地址 String ip = ShiroUtils.getIp(); operLog.setOperIp(ip); // 操作地点 operLog.setOperLocation(AddressUtils.getRealAddressByIP(ip)); operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); if (currentUser != null) { operLog.setOperName(currentUser.getLoginName()); if (StringUtils.isNotNull(currentUser.getDept()) && StringUtils.isNotEmpty(currentUser.getDept().getDeptName())) { operLog.setDeptName(currentUser.getDept().getDeptName()); } } if (e != null) { operLog.setStatus(BusinessStatus.FAIL); operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); } // 设置方法名称 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); operLog.setMethod(className + "." + methodName + "()"); // 处理设置注解上的参数 getControllerMethodDescription(controllerLog, operLog); // 保存数据库 operLogService.insertOperlog(operLog); } catch (Exception exp) { // 记录本地异常日志 log.error("==前置通知异常=="); log.error("异常信息:{}", exp.getMessage()); exp.printStackTrace(); } } /** * 获取注解中对方法的描述信息 用于Controller层注解 * * @param log 切点 * @return 方法描述 * @throws Exception */ public void getControllerMethodDescription(Log log, OperLog operLog) throws Exception { // 设置action动作 operLog.setAction(log.action()); // 设置标题 operLog.setTitle(log.title()); //设置具体操作 operLog.setOperating(log.operating()); // 设置channel operLog.setChannel(log.channel()); // 是否需要保存request,参数和值 if (log.isSaveRequestData()) { // 获取参数的信息,传入到数据库中。 setRequestValue(operLog); } } /** * 获取请求的参数,放到log中 * * @param operLog * @param operLog */ private void setRequestValue(OperLog operLog) { HttpServletRequest request=ServletUtils.getRequest(); Map<String, String[]> map = request.getParameterMap(); String params = JSONObject.toJSONString(map); operLog.setOperParam(StringUtils.substring(params, 0, 255)); } /** * 是否存在注解,如果存在就获取 */ private Log getAnnotationLog(JoinPoint joinPoint) throws Exception { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { return method.getAnnotation(Log.class); } return null; } }