这里基于struts2的拦截器来实现。
使用struts2拦截器拦截所有或者指定的请求,对用户操作过程中的:操作用户,操作时间,操作位置,操作结果,操作用时等信息的获取以及储存,方便将来数据的查询和显示。
操作日志信息
日志信息表的建表语句:
CREATE TABLE `audit_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
`user_name` varchar(50) DEFAULT NULL COMMENT '用户名/账号',
`ip` varchar(30) DEFAULT NULL COMMENT '用户IP',
`start_time` bigint(20) DEFAULT NULL COMMENT '开始时间',
`end_time` bigint(20) DEFAULT NULL COMMENT '结束时间',
`module` varchar(200) DEFAULT NULL COMMENT '模块描述',
`function` varchar(200) DEFAULT NULL COMMENT '功能描述',
`clazz` varchar(255) DEFAULT NULL COMMENT '所在类',
`method` varchar(100) DEFAULT NULL COMMENT 'Action方法名',
`result` varchar(255) DEFAULT NULL COMMENT '返回',
`use_time` bigint(20) DEFAULT NULL COMMENT '使用时间:毫秒',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
贴出对应的需要持久化的日志信息类:
package com.zkbc.core.dao.model;
import java.io.Serializable;
import java.util.Date;
public class AuditLog implements Serializable{
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.id
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private Long id;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.user_id
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private Long userId;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.user_name
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private String userName;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.ip
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private String ip;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.start_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private Long startTime;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.end_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private Long endTime;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.module
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private String module;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.function
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private String function;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.clazz
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private String clazz;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.method
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private String method;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.result
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private String result;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.use_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private Long useTime;
/**
* This field was generated by MyBatis Generator.
* This field corresponds to the database column audit_log.create_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
private Date createTime;
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.id
*
* @return the value of audit_log.id
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public Long getId() {
return id;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.id
*
* @param id the value for audit_log.id
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setId(Long id) {
this.id = id;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.user_id
*
* @return the value of audit_log.user_id
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public Long getUserId() {
return userId;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.user_id
*
* @param userId the value for audit_log.user_id
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setUserId(Long userId) {
this.userId = userId;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.user_name
*
* @return the value of audit_log.user_name
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public String getUserName() {
return userName;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.user_name
*
* @param userName the value for audit_log.user_name
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setUserName(String userName) {
this.userName = userName == null ? null : userName.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.ip
*
* @return the value of audit_log.ip
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public String getIp() {
return ip;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.ip
*
* @param ip the value for audit_log.ip
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setIp(String ip) {
this.ip = ip == null ? null : ip.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.start_time
*
* @return the value of audit_log.start_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public Long getStartTime() {
return startTime;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.start_time
*
* @param startTime the value for audit_log.start_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setStartTime(Long startTime) {
this.startTime = startTime;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.end_time
*
* @return the value of audit_log.end_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public Long getEndTime() {
return endTime;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.end_time
*
* @param endTime the value for audit_log.end_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setEndTime(Long endTime) {
this.endTime = endTime;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.module
*
* @return the value of audit_log.module
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public String getModule() {
return module;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.module
*
* @param module the value for audit_log.module
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setModule(String module) {
this.module = module == null ? null : module.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.function
*
* @return the value of audit_log.function
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public String getFunction() {
return function;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.function
*
* @param function the value for audit_log.function
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setFunction(String function) {
this.function = function == null ? null : function.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.clazz
*
* @return the value of audit_log.clazz
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public String getClazz() {
return clazz;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.clazz
*
* @param clazz the value for audit_log.clazz
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setClazz(String clazz) {
this.clazz = clazz == null ? null : clazz.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.method
*
* @return the value of audit_log.method
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public String getMethod() {
return method;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.method
*
* @param method the value for audit_log.method
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setMethod(String method) {
this.method = method == null ? null : method.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.result
*
* @return the value of audit_log.result
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public String getResult() {
return result;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.result
*
* @param result the value for audit_log.result
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setResult(String result) {
this.result = result == null ? null : result.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.use_time
*
* @return the value of audit_log.use_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public Long getUseTime() {
return useTime;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.use_time
*
* @param useTime the value for audit_log.use_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setUseTime(Long useTime) {
this.useTime = useTime;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column audit_log.create_time
*
* @return the value of audit_log.create_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public Date getCreateTime() {
return createTime;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column audit_log.create_time
*
* @param createTime the value for audit_log.create_time
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table audit_log
*
* @mbggenerated Thu May 03 16:04:24 CST 2018
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", userId=").append(userId);
sb.append(", userName=").append(userName);
sb.append(", ip=").append(ip);
sb.append(", startTime=").append(startTime);
sb.append(", endTime=").append(endTime);
sb.append(", module=").append(module);
sb.append(", function=").append(function);
sb.append(", clazz=").append(clazz);
sb.append(", method=").append(method);
sb.append(", result=").append(result);
sb.append(", useTime=").append(useTime);
sb.append(", createTime=").append(createTime);
sb.append("]");
return sb.toString();
}
}
拦截器
package com.yh.userAudit;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
import com.zkbc.base.BeanHelper;
import com.zkbc.core.dao.model.AuditLog;
import com.zkbc.core.dao.model.User;
import com.zkbc.core.service.IAuditLogService;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsStatics;
import org.springframework.beans.factory.BeanFactory;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
/**
* @Description: 用户审计数据记录拦截器
* @Author: 张颖辉(yh)
* @CreateDate: 2018/5/2 13:17
* @UpdateUser: 张颖辉(yh)
* @UpdateDate: 2018/5/2 13:17
* @UpdateRemark: The modified content
* @Version: 1.0
*/
public class AuditLogInterceptor extends MethodFilterInterceptor {
/**
* @Description: 拦截器方法
* @Author: 张颖辉(yh)
* @Date: 2018/5/2 13:52
* @param: [actioninvocation:action 调用对象]
* @return: java.lang.String
* @Version: 1.0
*/
@Override
protected String doIntercept(ActionInvocation actioninvocation) throws Exception {
AuditLog auditLog = new AuditLog();
Date startDate = new Date();
String result = actioninvocation.invoke();// 递归调用拦截器
/*时间相关*/
auditLog.setStartTime(startDate.getTime());// 设置开始时间long
Date endDate = new Date();
auditLog.setEndTime(endDate.getTime());// 设置结束时间long
auditLog.setCreateTime(startDate);//设置创建时间
auditLog.setUseTime(endDate.getTime() - startDate.getTime());//设置用时long
User user = (User) ServletActionContext.getRequest().getSession().getAttribute("user");
auditLog.setUserId(user.getUserId().longValue());// 设置登录用户的Id,在用户登录时把id保存到session中,这里可扩展判断用户是否登录的验证和权限验证
auditLog.setUserName(user.getNickName());
String methodName = actioninvocation.getProxy().getMethod();
if (methodName.length() > 0) {
Object action = actioninvocation.getAction();
Class clazz = action.getClass();
/*Action 类名*/
auditLog.setClazz(clazz.getName());
/*模块名称 如果设置了注解则读取注解的内容*/
if (clazz.isAnnotationPresent(AuditLogger.class)) {
AuditLogger talClazz = (AuditLogger) clazz
.getAnnotation(AuditLogger.class);
if (StringUtils.isNotBlank(talClazz.module())) {
auditLog.setModule(talClazz.module());
}
}
Method method = action.getClass().getMethod(methodName, null);
/*方法名称*/
auditLog.setMethod(methodName);
/*功能描述 如果设置了注解则读取注解的内容*/
if (method.isAnnotationPresent(AuditLogger.class)) {
AuditLogger alm = method
.getAnnotation(AuditLogger.class);
if (StringUtils.isNotBlank(alm.function())) {
auditLog.setFunction(alm.function());
}
}
String ip = ServletActionContext.getRequest().getRemoteAddr();
auditLog.setIp(ip);// 记录登录的IP,这里还可以对IP进行鉴权功能(允许或限制某些IP)
auditLog.setResult(result);// 记录登录时返回的结果.
//System.out.println("审计日志:" + auditLog);
/*审计日志持久化*/
addAuditLog(actioninvocation,auditLog);
}
return result; // 跳转
}
private void addAuditLog(ActionInvocation actioninvocation, AuditLog auditLog) {
//该方法自己实现,我使用的方法比较特殊,这里我就删除了。
}
}
注解类
package com.yh.userAudit;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Description: [用户安全审计] 模块功能标识注解
* @Author: 张颖辉(yh)
* @CreateDate: 2018/5/2 13:48
* @UpdateUser: 张颖辉(yh)
* @UpdateDate: 2018/5/2 13:48
* @UpdateRemark: The modified content
* @Version: 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.METHOD,
java.lang.annotation.ElementType.TYPE})
public @interface AuditLogger {
/*模块*/
String module() default "";
/*功能*/
String function() default "";
}
拦截器配置
然后将拦截器配置到 struts.xml中就可以了
1 标签<interceptors>下配置:
2 再配置拦截器栈interceptor-stack
3 将interceptor-stack配置到使用本拦截器的<package>标签下(应该是配置了登录拦截器的package)
注解的使用
上面定义的注解@AuditLogger 既可以在类上,也可以在方法上。
用在类上的时候,填入参数module=“模块描述”
用在方法上的时候,填入参数function=“功能描述”
如果没有注解,也会在数据库中保存本条操作记录,可上诉两个字段,值为null。不过即使没有注解,插入的数据中也会有访问的action类名,和方法名。所以在这里注解不是必须使用的,只是使用以后可以更方便知道用户操作的具体功能。
扩展
上面的方式是把所有用户登录后的操作保存(拦截器配置到了所有需要登录的package中)。
如果只需要记录一部分重要的操作,那么可以修改代码,只有被注释的类和方法才会在执行时持久化数据。
那么所有的重要操作必须都要加上注释,才能保证数据的完整。