系统操作日志切面

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声明一个切面。

猜你喜欢

转载自blog.csdn.net/qingmengwuhen1/article/details/80737034