spring AOP 为系统增加操作日志
方法一:
1. 实现操作日志的类
package com.huaxia.log.interceptor;
import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;
import com.huaxia.auth.domain.UserAccount;
import com.huaxia.base.service.UserAccountService;
import com.huaxia.log.domain.LogNameConfig;
import com.huaxia.log.domain.OperateLog;
import com.huaxia.log.service.OperateLogService;
public class LoggerBefore implements MethodBeforeAdvice {
/**
* Logger for this class
*/
private static final Logger logger = Logger.getLogger(LoggerBefore.class);
/**
* OperateLogService
*/
private OperateLogService logService;
/**
* userAccountService
*/
private UserAccountService userAccountService;
/**
* @param method
* @param objects
* @param o
* @throws Throwable
*/
public void before(Method method, Object[] objects, Object o)
throws Throwable {
UserAccount curUser = null;
String methodName = "execute";
String userIp = null;
String sessionId = null;
String clazzName = o.getClass().getSimpleName();
for (Object obj : objects) {
if (null == obj) {
continue;
}
if (obj instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) obj;
if ("LoginAction".equals(clazzName)) {
curUser = userAccountService.getUserAccountByUserid(request
.getParameter("userID"));
} else {
curUser = (UserAccount) request.getSession().getAttribute(
"HUAXIA_CURRENT_USER");
}
sessionId = request.getSession().getId();
if (StringUtils.isNotEmpty(request.getParameter("method"))) {
methodName = request.getParameter("method");
}
userIp = request.getRemoteAddr();
break;
}
}
if (null == curUser) {
logger.info("can not get session user.");
logger.info("logging before:" + o.getClass().getSimpleName()
+ methodName);
return;
}
LogNameConfig logCfg = this.logService.getLogNameConfig(clazzName,
methodName);
if (null != logCfg) {
if ("1".equals(logCfg.getLogFlag())) {
OperateLog log = new OperateLog();
log.setUserId(curUser.getUserID());
log.setUserName(curUser.getUserName());
log.setOperateTime(new Date());
log.setClassName(clazzName);
log.setOperateMethod(methodName);
log.setUserIp(userIp);
log.setSessionId(sessionId);
String operateName = logCfg.getOperateCnName();
if (null != operateName) {
log.setOperateCnName(operateName);
}
logService.addLog(log);
logger.info("userId:" + log.getUserId() + ",userIp:"
+ log.getUserIp() + ",className:" + log.getClassName()
+ ",operateMethod:" + log.getOperateMethod()
+ ",operateTime:" + log.getOperateTime());
}
}
}
/**
* @param pLogService
* the logService to set
*/
public void setLogService(OperateLogService pLogService) {
logService = pLogService;
}
public void setUserAccountService(UserAccountService userAccountService) {
this.userAccountService = userAccountService;
}
}
2.配置spring.xml文件
<bean name="logger" class="com.huaxia.log.interceptor.LoggerBefore">
<property name="logService" ref="logService" />
<property name="userAccountService" ref="userAccountService" />
</bean>
<bean name="loggerAutoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>/*</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>logger</value>
</list>
</property>
</bean>
方法二:采用注解的方式
1.生成自定义注解
package com.huaxia.traffic.app.common.log;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String description() default "";
}
2.spring AOP 拦截切入点
package com.huaxia.traffic.app.common.log;
import java.lang.reflect.Method;
import java.util.Date;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.huaxia.traffic.app.common.domain.OperateLog;
import com.huaxia.traffic.app.common.log.service.OperateLogService;
import com.huaxia.traffic.app.enterprise.domain.EnterpriseOperator;
import com.huaxia.traffic.app.enterprise.domain.EnterpriseOperatorLogin;
@Component
@Aspect
public class LoggerBefore {
/**
* Logger for this class
*/
private static final Logger logger = Logger.getLogger(LoggerBefore.class);
/**
* OperateLogService
*/
@Autowired
private OperateLogService logService;
@Pointcut("@annotation(com.huaxia.traffic.app.common.log.SystemControllerLog)")
public void controllerAspect() {
}
@SuppressWarnings("rawtypes")
public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
description = method.getAnnotation(SystemControllerLog.class).description();
break;
}
}
}
return description;
}
/**
* @param method
* @param objects
* @param o
* @throws Throwable
*/
@After("controllerAspect()")
public void before(JoinPoint joinPoint) throws Throwable {
EnterpriseOperator curUser = null;
String userIp = null;
String sessionId = null;
String clazzName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] objects = joinPoint.getArgs();
Class targetClass = Class.forName(clazzName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == objects.length) {
description = method.getAnnotation(SystemControllerLog.class).description();
break;
}
}
}
logger.info("clazzName=" + clazzName + ",method=" + methodName + ",args=" + objects);
Subject subject = SecurityUtils.getSubject();
userIp=subject.getSession().getHost();
sessionId=subject.getSession().getId().toString();
Object user = subject.getPrincipal();
logger.info(user);
if (user instanceof EnterpriseOperator) {
curUser = (EnterpriseOperator) user;
OperateLog log = new OperateLog();
log.setUserId(String.valueOf(curUser.getId()));
log.setUserName(curUser.getUsername());
log.setOperateTime(new Date());
log.setClassName(clazzName);
log.setOperateMethod(methodName);
log.setUserIp(userIp);
log.setSessionId(sessionId);
log.setOperateCnName(description);
logService.addLog(log);
}
}
}
3.自定义注解用法
@ResponseBody
@RequestMapping(value = "/logout")
@SystemControllerLog(description="登出")
public ReturnBean logout(HttpServletRequest request) {
Subject currentUser = SecurityUtils.getSubject();
EnterpriseOperator user = (EnterpriseOperator) currentUser.getPrincipal();
LOGGER.info(ToStringBuilder.reflectionToString(user));
enterpriseOperatorLoginService.invalidToken(user);
if (currentUser.isAuthenticated()) {
currentUser.logout();
//session.invalidate();
}
ReturnBean bean = new ReturnBean();
bean.setSuccess(ReturnBean.SUCCESS);
bean.setData(null);
bean.setMessage("注销用户成功");
return bean;
}
方法二 可以自己给方法取名字比方法一好用