Java使用aop實現操作日志


1、設計數據表

-- ----------------------------
-- Table structure for t_log
-- ----------------------------
DROP TABLE IF EXISTS `t_log`;
CREATE TABLE `t_log` (
  `id` int(11) NOT NULL auto_increment COMMENT '操作日志id',
  `username` varchar(20) default NULL COMMENT '操作人',
  `module` varchar(30) default NULL COMMENT '執行模塊',
  `methods` varchar(50) default NULL COMMENT '執行方法',
  `content` varchar(255) default NULL COMMENT '操作內容',
  `actionurl` varchar(50) default NULL COMMENT '請求路徑',
  `ip` varchar(50) default NULL COMMENT 'IP地址',
  `date` datetime default NULL COMMENT '操作時間',
  `commite` tinyint(2) default NULL COMMENT '執行描述(1:執行成功、2:執行失敗)',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

2、實體類

import java.util.Date;

public class Log {
    private Integer id;//操作日志ID

    private String username;//操作人

    private String module;//操作模塊

    private String methods;//執行方法

    private String content;//操作內容

    private String actionurl;//請求路徑

    private String ip;//IP

    private Date date;//操作時間

    private Byte commite;//執行描述(1:執行成功、2:執行失敗)

}

3、Spring配置文件添加AOP配置

<!--xml頭部配置aop-->
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd


<!-- 操作日志配置 指定掃描aop執行操作的類 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="logAopAction" class="com.saffi.action.LogAopAction"/>

4、自定義注解

import java.lang.annotation.*;
/**
 * <p>Title: SystemLog</p>  
 * <p>Description:自定義操作日志標簽,模塊名和方法名 </p>  
 * @author Saffichan
 * @date 2018-06-01 15:57
 */

@Target({ElementType.PARAMETER, ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented
public @interface OptionalLog {
    String module()  default "";  
    String methods()  default "";
}

 

5、Controller層

/**  
* <p>Title: LogAopAction.java</p>  
* <p>Description: 操作日志Controller</p>  
* <p>Company: </p>  
* @author Saffichan 
* @date 2018-06-01 15:38
* @version 1.0  
*/import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import com.saffi.web.BaseAction;
import com.saffi.common.util.MapperUtil;
import com.saffi.system.bo.LogBO;
import com.saffi.service.LogService;
import com.saffi.user.bo.AdminBO;
import com.saffi.web.annotation.PermssionMethodCode;

@Aspect
public class LogAopAction {
    // 注入service,用來將日志信息保存在數據庫
    @Resource(name = "logService")
    private LogService logService;

    // 配置接入點,即為所要記錄的action操作目錄
    @Pointcut("execution(* com.saffi.*.action..*.*(..))")
    private void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //日志實體對象
        LogBO logBo = new LogBO();

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        // 從session獲取用戶名
         String username = request.getSession().getAttribute("user");
         logBo.setUsername(username);
     // 獲取系統當前時間
        logBo.setDate(new Date());

        // 獲取訪問真實IP    
        String ipAddress = request.getHeader("x-forwarded-for");  
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
            ipAddress = request.getHeader("Proxy-Client-IP");  
        }  
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
            ipAddress = request.getHeader("WL-Proxy-Client-IP");  
        }  
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
            ipAddress = request.getRemoteAddr();  
            if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){  
                //根據網卡取本機配置的IP  
                InetAddress inet=null;  
                try {  
                    inet = InetAddress.getLocalHost();  
                } catch (UnknownHostException e) {  
                    e.printStackTrace();  
                }  
                ipAddress= inet.getHostAddress();  
            }  
        }  
        //對於通過多個代理的情況,第一個IP為客戶端真實IP,多個IP按照','分割  
        if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15  
            if(ipAddress.indexOf(",")>0){  
                ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));  
            }  
        }  
            
        logBo.setIp(ipAddress);
                 
        // 攔截的實體類,就是當前正在執行的controller
        Object target = pjp.getTarget();
        // 攔截的方法名稱。當前正在執行的方法
        String methodName = pjp.getSignature().getName();
        // 攔截的方法參數
        Object[] args = pjp.getArgs();
        
        //獲取請求路徑
        String actionUrl = request.getRequestURI();      
        
        // 攔截的放參數類型
        Signature sig = pjp.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("該注解只能用於方法");
        }
        msig = (MethodSignature) sig;
        Class[] parameterTypes = msig.getMethod().getParameterTypes();

        Object object = null;
        // 獲得被攔截的方法
        Method method = null;
        
        
        try {
            method = target.getClass().getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e1) {
            e1.printStackTrace();
        } catch (SecurityException e1) {
            e1.printStackTrace();
        }
        if (null != method) {
            // 獲取方法(此為自定義注解) 
           OptionalLog op = method.getAnnotation(OptionalLog .class);
    
            // 獲取注解的modules 設為操作模塊
            logBo.setModule(op.modules());        
            // 獲取注解的methods 設為執行方法
            logBo.setMethods(op.methods());    
            // 將上面獲取到的請求路徑 設為請求路徑
            logBo.setActionurl(actionUrl);
            try {
                object = pjp.proceed();
                //接受客戶端的數據
                Map<String,String[]> map = request.getParameterMap(); 
          // 解決獲取參數亂碼 Map<String,String[]> newmap = new HashMap<String,String[]>(); for(Map.Entry<String, String[]> entry : map.entrySet()){ String name = entry.getKey(); String values[] = entry.getValue(); if(values==null){ newmap.put(name, new String[]{}); continue; } String newvalues[] = new String[values.length]; for(int i=0; i<values.length;i++){ String value = values[i]; value = new String(value.getBytes("iso8859-1"),request.getCharacterEncoding()); newvalues[i] = value; //解決亂碼后封裝到Map中 } newmap.put(name, newvalues); } logBo.setContent(MapperUtil.toJsonStr(newmap)); //1為執行成功 logBo.setCommite((byte) 1); // 添加到數據庫 logService.add(logBo); } catch (Throwable e) {
         //接受客戶端的數據
Map
<String,String[]> map = request.getParameterMap();
       // 解決獲取參數亂碼 Map<String,String[]> newmap = new HashMap<String,String[]>(); for(Map.Entry<String, String[]> entry : map.entrySet()){ String name = entry.getKey(); String values[] = entry.getValue(); if(values==null){ newmap.put(name, new String[]{}); continue; } String newvalues[] = new String[values.length]; for(int i=0; i<values.length;i++){ String value = values[i]; value = new String(value.getBytes("iso8859-1"),request.getCharacterEncoding()); newvalues[i] = value; //解決亂碼后封裝到Map中 } newmap.put(name, newvalues); }
         //MapperUtil.toJsonStr為自定義的轉換工具類 logBo.setContent(MapperUtil.toJsonStr(newmap));
//2為執行失敗 logBo.setCommite((byte) 2);
         //添加到數據庫 logService.add(logBo); } }
return object; } }

6、具體操作action使用方法

     /**
     * <p>Description:查詢所有操作日志 </p>  
     * @author Saffichan
     * */
    @OptionalLog(modules="操作日志", methods="查詢操作日志")
    @RequestMapping("/query")
    public void listLogInfo(){
    }    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM