Implementation of user operation logging based on struts 2 interceptor

Here based on struts 2 interceptor to achieve.

Use struts 2 interceptor to intercept all or specified requests, acquire and store the information such as operation user, operation time, operation location, operation result and operation time in the process of user operation, so as to facilitate the query and display of data in the future.

Operation log information

Table creation statement of log information table:

CREATE TABLE `audit_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
  `user_id` bigint(20) DEFAULT NULL COMMENT 'user id',
  `user_name` varchar(50) DEFAULT NULL COMMENT 'User name/Account number',
  `ip` varchar(30) DEFAULT NULL COMMENT 'user IP',
  `start_time` bigint(20) DEFAULT NULL COMMENT 'start time',
  `end_time` bigint(20) DEFAULT NULL COMMENT 'End time',
  `module` varchar(200) DEFAULT NULL COMMENT 'Module description',
  `function` varchar(200) DEFAULT NULL COMMENT 'Function description',
  `clazz` varchar(255) DEFAULT NULL COMMENT 'Location class',
  `method` varchar(100) DEFAULT NULL COMMENT 'Action Method name',
  `result` varchar(255) DEFAULT NULL COMMENT 'Return',
  `use_time` bigint(20) DEFAULT NULL COMMENT 'Usage time: ms',
  `create_time` datetime DEFAULT NULL COMMENT 'Creation time',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;

Post the corresponding log information class to be persisted:

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();
    }
}

Interceptor

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: User audit data logging interceptor
 * @Author: Zhang Yinghui (yh)
 * @CreateDate: 2018/5/2 13:17
 * @UpdateUser: Zhang Yinghui (yh)
 * @UpdateDate: 2018/5/2 13:17
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
public class AuditLogInterceptor extends MethodFilterInterceptor {
    /**
     * @Description: Interceptor method
     * @Author: Zhang Yinghui (yh)
     * @Date: 2018/5/2 13:52
     * @param: [actioninvocation:action Call object]
     * @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();// Recursive call interceptor
        /*Time correlation*/
        auditLog.setStartTime(startDate.getTime());// Set start time long
        Date endDate = new Date();
        auditLog.setEndTime(endDate.getTime());// Set end time long
        auditLog.setCreateTime(startDate);//Set creation time
        auditLog.setUseTime(endDate.getTime() - startDate.getTime());//Set time long
        User user = (User) ServletActionContext.getRequest().getSession().getAttribute("user");
        auditLog.setUserId(user.getUserId().longValue());// Set the id of the login user, and save the id to the session when the user logs in. Here, you can extend the authentication and permission authentication to judge whether the user logs in or not
        auditLog.setUserName(user.getNickName());
        String methodName = actioninvocation.getProxy().getMethod();
        if (methodName.length() > 0) {
            Object action = actioninvocation.getAction();
            Class clazz = action.getClass();
            /*Action Class name*/
            auditLog.setClazz(clazz.getName());
            /*Module name read the content of the annotation if the annotation is set*/
            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);
            /*Method name*/
            auditLog.setMethod(methodName);
            /*Function description read the content of the annotation if it is set*/
            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);// Record the logged in IP. Here you can also authenticate the IP (allow or restrict some IP)
            auditLog.setResult(result);// Record the results returned when logging in

            //System.out.println("audit log:" + auditLog);
            /*Audit log persistence*/
            addAuditLog(actioninvocation,auditLog);
        }
        return result; // Jump
    }

    private void addAuditLog(ActionInvocation actioninvocation, AuditLog auditLog) {
     //This method is implemented by myself. The method I use is quite special. Here I delete it.
    }
}

Annotation

package com.yh.userAudit;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Description: [User security audit] module function identification notes
 * @Author: Zhang Yinghui (yh)
 * @CreateDate: 2018/5/2 13:48
 * @UpdateUser: Zhang Yinghui (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 {
    /*Modular*/
    String module() default "";

    /*function*/
    String function() default "";
}

Interceptor configuration

Then configure the interceptor to struts.xml

1 configuration under < interceptors > tag:

2. Reconfigure interceptor stack

3. Configure the interceptor stack under the < package > tab of this interceptor (it should be the package with the login interceptor configured)

Use of annotations

The annotation @ AuditLogger defined above can be on either a class or a method.

When it is used on a class, fill in the parameter module = "module description"

When using the method, fill in the parameter function = "function description"

If there is no annotation, this operation record will also be saved in the database. Two fields can be appealed and the value is null. However, even if there is no annotation, there will be the action class name and method name accessed in the inserted data. Therefore, the annotation here is not necessary, but it is more convenient to know the specific functions of user operation after use.

extend

The above method is to save the operations after all users log in (the interceptor is configured to all package s that need to log in).

If only some important operations need to be recorded, the code can be modified, and only the annotated classes and methods will persist the data during execution.

Then all important operations must be annotated to ensure the integrity of the data.

Keywords: Database Mybatis Java Struts

Added by agge on Mon, 23 Mar 2020 17:56:45 +0200