Appfuse:記錄操作日誌

消失的風發表於2015-07-14

appfuse的資料維護操作都發生在***form頁面,與之對應的是***FormController,在Controller中處理資料的操作是onSubmit方法,既然所有的操作都通過onSubmit,那麼只需要攔截onSubmit並記錄對應的引數即可作為操作日誌。

首先要攔截Controller層的方法就需要在dispatcher-servlet.xml中配置攔截器,如下:

<aop:config>
        <aop:advisor id="submitTx" advice-ref="txSubmitAdvice"
            pointcut="execution(* *..controller.*Controller.onSubmit(..))" order="0" />
    </aop:config>
    <bean id="txSubmitAdvice" class="com.zcmp.xunji.service.SubmitAdvice"/>
dispatcher-servlet.xml

接下來在Service中定義自己的AOP攔截器

package com.disappearwind.service;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

import com.disappearwind.model.BaseObject;
import com.disappearwind.model.Role;
import com.disappearwind.model.Syslog;
import com.disappearwind.model.User;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

/**
 * 對Controller中的onSubmit方法監聽,記錄使用者的操作日誌
 * 
 * @author mraible
 */
public class SubmitAdvice implements AfterReturningAdvice, MethodInterceptor {

    private final Log log = LogFactory.getLog(SubmitAdvice.class);
    private UserManager userManager = null;
    private GenericManager<Syslog, Long> syslogManager;

    @Autowired
    public void setSyslogManager(
            @Qualifier("syslogManager") GenericManager<Syslog, Long> syslogManager) {
        this.syslogManager = syslogManager;
    }

    @Autowired
    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }

    /**
     * 在使用者的業務操作執行完之後記錄操作日誌
     * 
     * @param returnValue
     *            the user object
     * @param method
     *            the name of the method executed
     * @param args
     *            the arguments to the method
     * @param target
     *            the target class
     * @throws Throwable
     *             thrown when args[0] is null or not a Base object
     */
    public void afterReturning(Object returnValue, Method method,
            Object[] args, Object target) throws Throwable {
        // 方法簽名:String onSubmit(AppToken appToken, BindingResult errors,
        // HttpServletRequest request,HttpServletResponse response)
        try {
            if (args[0] instanceof BaseObject) {
                BaseObject obj = (BaseObject) args[0];
                HttpServletRequest request = (HttpServletRequest) args[2];
                // 發生在哪個Model
                String modelName = obj.getClass().getSimpleName();
                // Model中的資料
                String modelData = obj.toString();
                // 操作型別,request引數中sava就是Save,request引數中有delete則是Delete
                String action = "Save";
                if (null != request.getParameter("delete")) {
                    action = "Delete";
                }

                // 記錄操作日誌到資料庫
                Syslog syslog = new Syslog();
                syslog.setModule(modelName + "." + action);
                syslog.setContent(modelData);
                syslog.setCreateDate(new Date());
                syslog.setCreator(getCurrentUserID());

                syslogManager.save(syslog);
            }
        } catch (Exception ex) {
            log.error(ex);
        }
    }

    /**
     * 獲取當前操作的使用者
     * 
     * @return 使用者ID
     */
    private Long getCurrentUserID() {
        Long userID = 0l;
        SecurityContext ctx = SecurityContextHolder.getContext();
        if (ctx.getAuthentication() != null) {
            Authentication auth = ctx.getAuthentication();
            UserDetails user = (UserDetails) auth.getPrincipal();
            userID = this.userManager.getUserByUsername(user.getUsername())
                    .getId();
        }
        return userID;
    }
}
SubmitAdvice

注意,其中有一段是獲取當前登入使用者的ID的getCurrentUserID。

Syslog是自己定義的儲存日誌的資料結構。

相關文章