使用AOP实现系统的操作日志

更详细步骤可参考:(199条消息) springboot + 操作日志添加_往事不堪回首..的博客-CSDN博客

1. AOP切面类

@Aspect
@Component
public class OperationLogAspect {

	Logger logger = LoggerFactory.getLogger(getClass());

	private String getIP(HttpServletRequest request) {
		String strip = request.getHeader("X-Real-IP");//request.getRemoteAddr();// 
		if (ObjectUtil.isEmpty(strip)) {
			InetAddress address;
			try {
				String localIP = request.getRemoteAddr();
				if (ObjectUtil.isNotEmpty(localIP) && !("0:0:0:0:0:0:0:1".equals(localIP))) {
					strip = localIP;
				}
				else {
					address = InetAddress.getLocalHost();
					strip = address.getHostAddress();//返回IP地址
				}
			} catch (UnknownHostException e) {
				e.printStackTrace();
				logger.error("获取客户端IP失败:"+e.getMessage());
			}
	}
		return strip;
	}

	// 当前包所有以insert开头的方法
	@Pointcut("execution(public * com.xxx.controller..*.insert*(..))")
	public void insertOperate() {
	}

	// 当前包所有以update开头的方法
	@Pointcut("execution(public * com.xxx.controller..*.update*(..))")
	public void updateOperate() {
	}

	// 当前包所有以delete开头的方法
	@Pointcut("execution(public * com.xxx.controller..*.delete*(..))")
	public void delOperate() {
	}

	@After("insertOperate()")
	public void insertOperationContent(JoinPoint joinPoint) throws Throwable {
		System.out.println("aspecting...");
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		HttpSession session = request.getSession();
		 String strUserID = String.valueOf(session.getAttribute("loginuserid"));
		 Integer userid = 0;
		 if (ObjectUtil.isNotEmpty(strUserID)) {
			 userid = Integer.parseInt((String)strUserID);
		 }
		String strOperationContent = (String)(session.getAttribute("operationSession"));// ThreadLocalSessionUtils.getThreadLocalMsg();
		String strOperateIP = getIP(request);

		if (ObjectUtil.isNotEmpty(strOperationContent)) {
			OperateLogBean operateLog = new OperateLogBean();
			operateLog.setUserID(userid);
			operateLog.setOperateType("新增");
			operateLog.setOperateContent(strOperationContent);
			operateLog.setOperateIP(strOperateIP);
			operateLog.setOperateDT(new Date());
			MapperManager.aspectMapper.insertOperateLog(operateLog);
			System.out.println("insert... aspecting 取得... :" + strOperationContent);
			session.removeAttribute("operationSession");
		} else {
			System.out.println("Session operationSession的值为空...");
		}
	}

	@After("updateOperate()")
	public void updateOperationContent(JoinPoint joinPoint) throws Throwable {
		//与insertOperationContent方法类似,只是插入log的数据不相同(例如“新增” 变成 “更新”)
	}

	@After("delOperate()")
	public void delOperationContent(JoinPoint joinPoint) throws Throwable {
		//与insertOperationContent方法类似,只是插入log的数据不相同(例如“新增” 变成 “删除”)
	}

	// 当前包所有以ajax开头的方法,即所有菜单的入口(因有导航栏的原因,所有菜单都是使用ajax请求局部刷新作为页面跳转的),都要清除operationLoglist的session值
	//如果页面没有各菜单页面之间的跳转不是使用的ajax,那也需要一个相同的格式去写跳转页面方法,利于清空session中保存的日志
	@Pointcut("execution(public * com.xxx.controller..*.ajax*(..))")
	public void ajaxOperate() {
	}

	@Before("ajaxOperate()")
	public void removeSession(JoinPoint joinPoint) throws Throwable {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		HttpSession session = request.getSession();
		session.removeAttribute("operationLoglist");
	}
}

2. 需要写操作日志的被拦截方法的实现 (需要拦截方法在切面类中有定义拦截xx路径下的所有xxx开头的方法,例如下面的方法就是被拦截以delete开头的方法)

@RequestMapping(value = "/deleteTr")
	public String deleteTr(Entity en, HttpSession session) { 
		String result = xxxxxxxxxx 删除动作 xxxxxxxxxxxx;

		if ("删除成功".equals(result)) { //判断操作成功还是失败,成功才插入日志
			String userId= session.getAttribute("userId").toString();
			session.setAttribute("operationSession", "【" + userId+ "】删除了xxx");
		}
		return result;
	}

你可能感兴趣的:(java,java,开发语言,后端)