基于struts2拦截器实现用户操作日志记录

这里基于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中)。

如果只需要记录一部分重要的操作,那么可以修改代码,只有被注释的类和方法才会在执行时持久化数据。

那么所有的重要操作必须都要加上注释,才能保证数据的完整。

猜你喜欢

转载自my.oschina.net/iyinghui/blog/1806346