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"/>
接下來在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; } }
注意,其中有一段是獲取當前登入使用者的ID的getCurrentUserID。
Syslog是自己定義的儲存日誌的資料結構。