在建的项目需要实现一个详细记录操作日志的需求:即哪个用户在什么时间做了什么操作,需要把这些日志记录到数据库,提供相应的用户查询、统计以及做一些日志审核。
项目的基本架构:SSH 即[Spring(v2)、struts(v1)、hibernate(v3)]
为了减小在建项目人力成本、降低修改程度、降低系统的耦合性,同时该项目spring配置中定义的Action bean的名称比较规范统一,所以就考虑用Spring AOP来完成日志记录。
代码及详细配置如下:【只是初步设计,如果要记录到数据库,注入相应的service即可】
前置消息:LogBeforeAdvice.java
Java代码
package aoplog;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;
import domain.UserAccount;
/**
*
* @author Michael
*/
public class LogBeforeAdvice implements MethodBeforeAdvice {
/**
* Logger for this class
*/
private static final Logger logger = Logger
.getLogger(LogBeforeAdvice.class);
/**
* @param method
* @param args
* @param target
* @throws Throwable
*/
public void before(Method method, Object[] args, Object target)
throws Throwable {
UserAccount curUser = null;
String methodName = "execute";
for (Object obj : args) {
if (null == obj) {
continue;
}
if (obj instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) obj;
curUser = (UserAccount) request.getSession().getAttribute(
"HUAXIA_CURRENT_USER");
if (StringUtils.isNotEmpty(request.getParameter("method"))) {
methodName = request.getParameter("method");
}
}
}
if (null == curUser) {
logger.info("can not get session user.");
} else {
logger.info("operate user:" + curUser.getUserID());
}
logger.info("logging before advice. class:"
+ target.getClass().getSimpleName() + " method:" + methodName);
}
}
package aoplog;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;
import domain.UserAccount;
/**
*
* @author Michael
*/
public class LogBeforeAdvice implements MethodBeforeAdvice {
/**
* Logger for this class
*/
private static final Logger logger = Logger
.getLogger(LogBeforeAdvice.class);
/**
* @param method
* @param args
* @param target
* @throws Throwable
*/
public void before(Method method, Object[] args, Object target)
throws Throwable {
UserAccount curUser = null;
String methodName = "execute";
for (Object obj : args) {
if (null == obj) {
continue;
}
if (obj instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) obj;
curUser = (UserAccount) request.getSession().getAttribute(
"HUAXIA_CURRENT_USER");
if (StringUtils.isNotEmpty(request.getParameter("method"))) {
methodName = request.getParameter("method");
}
}
}
if (null == curUser) {
logger.info("can not get session user.");
} else {
logger.info("operate user:" + curUser.getUserID());
}
logger.info("logging before advice. class:"
+ target.getClass().getSimpleName() + " method:" + methodName);
}
}
后置消息:LogAfterAdvice.java
Java代码
package aoplog;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice;
import domain.UserAccount;
/**
* @author Michael
*/
public class LogAfterAdvice implements AfterReturningAdvice {
/**
* Logger for this class
*/
private static final Logger logger = Logger.getLogger(LogAfterAdvice.class);
/**
* @param returnObj
* @param method
* @param args
* @param target
* @throws Throwable
*/
public void afterReturning(Object returnObj, Method method, Object[] args,
Object target) throws Throwable {
UserAccount curUser = null;
String methodName = "execute";
for (Object obj : args) {
if (null == obj) {
continue;
}
if (obj instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) obj;
curUser = (UserAccount) request.getSession().getAttribute(
"HUAXIA_CURRENT_USER");
if (StringUtils.isNotEmpty(request.getParameter("method"))) {
methodName = request.getParameter("method");
}
}
}
if (null == curUser) {
logger.info("can not get session user.");
} else {
logger.info("operate user:" + curUser.getUserID());
}
logger.info("logging after advice. return obj:" + returnObj);
logger.info("logging after advice. class:"
+ target.getClass().getSimpleName() + " method:" + methodName);
}
}
package aoplog;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice;
import domain.UserAccount;
/**
* @author Michael
*/
public class LogAfterAdvice implements AfterReturningAdvice {
/**
* Logger for this class
*/
private static final Logger logger = Logger.getLogger(LogAfterAdvice.class);
/**
* @param returnObj
* @param method
* @param args
* @param target
* @throws Throwable
*/
public void afterReturning(Object returnObj, Method method, Object[] args,
Object target) throws Throwable {
UserAccount curUser = null;
String methodName = "execute";
for (Object obj : args) {
if (null == obj) {
continue;
}
if (obj instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) obj;
curUser = (UserAccount) request.getSession().getAttribute(
"HUAXIA_CURRENT_USER");
if (StringUtils.isNotEmpty(request.getParameter("method"))) {
methodName = request.getParameter("method");
}
}
}
if (null == curUser) {
logger.info("can not get session user.");
} else {
logger.info("operate user:" + curUser.getUserID());
}
logger.info("logging after advice. return obj:" + returnObj);
logger.info("logging after advice. class:"
+ target.getClass().getSimpleName() + " method:" + methodName);
}
}
spring配置文件部分代码
Xml代码
<!-- aop log cfg 自动代理 -->
<bean name="logBefore" class="aoplog.LogBeforeAdvice"></bean>
<bean name="logAfter" class="aoplog.LogAfterAdvice"></bean>
<bean name="loggerAutoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Action</value>
<value>*Logout</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>logBefore</value>
<value>logAfter</value>
</list>
</property>
</bean>
<!-- aop log cfg 自动代理 -->
<bean name="logBefore" class="aoplog.LogBeforeAdvice"></bean>
<bean name="logAfter" class="aoplog.LogAfterAdvice"></bean>
<bean name="loggerAutoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Action</value>
<value>*Logout</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>logBefore</value>
<value>logAfter</value>
</list>
</property>
</bean>
部分日志信息:
INFO - LogBeforeAdvice.before(51) | operate user:admin
INFO - LogBeforeAdvice.before(53) | logging before advice.
class:UserAccountMainAction method:displayUserAccountMainScreen
INFO - LogAfterAdvice.afterReturning(51) | operate user:admin
INFO - LogAfterAdvice.afterReturning(53) | logging after advice.
returnobj:ForwardConfig[name=UserAccountMain.screen,
path=/UserAccountMain.jsp,redirect=false,contextRelative=false,module=null]
INFO - LogAfterAdvice.afterReturning(54) | logging after advice.
class:UserAccountMainAction method:displayUserAccountMainScreen