使用SpringAOP编写日志记录(插入oracle数据库中)

代码较多,请耐心调试


首先oracle数据库表创建语句:

drop table cmu_system_log;

CREATE TABLE CMU_SYSTEM_LOG (
log_id INTEGER primary key ,
user_id INTEGER ,
username VARCHAR2(20)  ,
description VARCHAR2(50)  ,
methods VARCHAR2(500)  ,
log_type VARCHAR2(50) ,
request_ip INTEGER ,
exceptioncode VARCHAR2(255)  ,
exception_detail VARCHAR2(255)  ,
params VARCHAR2(255) ,
time DATE DEFAULT SYSDATE

);


需要在:Spring-mvc.xml中增加:


    
    


pom.xml里面需要导入:


            org.aspectj
            aspectjrt
            1.8.10
        

 
        org.springframework  
        spring-aop  
        4.2.5.RELEASE  
        


编写以下主要四个文件:


SysLog.java

package com.security.annotation;

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

@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
    /** 要执行的操作类型比如:add操作 **/
    public String operationType() default "";

    /** 要执行的具体操作比如:添加用户 **/
    public String operationName() default "";
}



SystemControllerLog.java

package com.security.annotation;

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

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

最重要的文件:SystemLogAspect.java

package com.security.annotation;

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

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

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.community.service.SystemLogService;
import com.community.util.IpUtil;
import com.oracle.pojo.SystemLog;
import com.oracle.pojo.Users;

@Aspect
@Component
public class SystemLogAspect {
    // 使用service注入功能把日志写进数据库中
    @Resource
    private SystemLogService systemLogService;

    private static final Logger logger = LoggerFactory
            .getLogger(SystemLogAspect.class);

    // Conntroller层的切点
    @Pointcut("@annotation(com.security.annotation.SysLog)")
    public void controllerAspect() {
    }

    /**
     * 编写后置通知,用于拦截Controller 层记录用户的操作
     * 
     * joinPoint 切点
     */
    @After("controllerAspect()")
    public void after(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        Users user = (Users) SecurityUtils.getSubject().getPrincipal();
        String userName = null;
        String userId = null;
        if (user != null) {
            Subject currentUser = SecurityUtils.getSubject();
            userId = currentUser.getSession().getAttribute("_USER_ID")
                    .toString();
            userName = (String) user.getUsername();
        }
        // 请求的IP
        String ip = request.getRemoteAddr();
        try {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] arguments = joinPoint.getArgs();
            Class targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getMethods();
            String operationType = "";
            String operationName = "";
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    Class[] clazzs = method.getParameterTypes();
                    if (clazzs.length == arguments.length) {
                        operationType = method.getAnnotation(SysLog.class)
                                .operationType();
                        operationName = method.getAnnotation(SysLog.class)
                                .operationName();
                        break;
                    }
                }
            }
            // 数据库日志
            SystemLog log = new SystemLog();
            log.setUserId(new Integer(userId));// 登录的用户id
            log.setUsername(userName);// 这里需要获取用户名
            log.setDescription(operationName);
            log.setMethods((joinPoint.getTarget().getClass().getName() + "."
                    + joinPoint.getSignature().getName() + "()"));
            log.setLogType(operationType);
            log.setRequestIp(IpUtil.ipToInt(ip));
            log.setExceptioncode(null);
            log.setExceptionDetail(null);
            log.setParams(null);
            log.setTime(new Date());
            // 保存数据库
            systemLogService.insertSelective(log);
            System.out.println("=====controller后置通知成功结束=====");
        } catch (Exception e) {
            // 记录本地异常日志
            logger.error("===后置通知异常===");
            logger.error("异常信息:{}", e.getMessage());
        }
    }

    /**
     * 异常通知 用于拦截记录异常日志
     */
    @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        Users user = (Users) SecurityUtils.getSubject().getPrincipal();
        String userName = null;
        String userId = null;
        if (user != null) {
            Subject currentUser = SecurityUtils.getSubject();
            userId = currentUser.getSession().getAttribute("_USER_ID")
                    .toString();
            userName = (String) user.getUsername();
        }
        // 请求的IP
        String ip = request.getRemoteAddr();
        String params = "";
        if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {

            params = Arrays.toString(joinPoint.getArgs());
        }
        try {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] arguments = joinPoint.getArgs();
            Class targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getMethods();
            String operationType = "error";
            String operationName = "";
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    Class[] clazzs = method.getParameterTypes();
                    if (clazzs.length == arguments.length) {
                        operationType = method.getAnnotation(SysLog.class)
                                .operationType();
                        operationName = method.getAnnotation(SysLog.class)
                                .operationName();
                        break;
                    }
                }
            }
            // ====数据库日志=====
            SystemLog log = new SystemLog();
            log.setUserId(new Integer(userId));// 登录的用户id
            log.setUsername(userName);// 这里需要获取用户名
            log.setDescription(operationName);
            log.setMethods((joinPoint.getTarget().getClass().getName() + "."
                    + joinPoint.getSignature().getName() + "()")
                    + "." + operationType);
            log.setLogType(operationType);
            log.setRequestIp(IpUtil.ipToInt(ip));
            log.setExceptioncode(null);
            log.setExceptionDetail(null);
            log.setParams(null);
            log.setTime(new Date());
            // 保存数据库
            systemLogService.insertSelective(log);
            System.out.println("=====异常通知结束=====");
        } catch (Exception ex) {
            // 记录本地异常日志
            logger.error("==异常通知异常==");
            logger.error("异常信息:{}", ex.getMessage());
        }
        // 记录本地异常日志
        logger.error("异常方法:{}异常代码:{}异常信息:{}参数:{}", joinPoint.getTarget()
                .getClass().getName()
                + joinPoint.getSignature().getName(), e.getClass().getName(),
                e.getMessage(), params);
    }
}


SystemServiceLog.java


package com.security.annotation;

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

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


SytemLogcontroller.java  负责与前端交互


package com.community.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.community.pager.PageInfo;
import com.community.service.SystemLogService;

@Controller
@Scope(value = "prototype")
@RequestMapping(value = "systemlog")
public class SystemLogController extends BaseController {
    @Autowired
    SystemLogService systemLogService;

    /**
     * 跳转到日志展示界面 权限控制判断 目前没有增加判断,仅跳转使用
     */
    @RequestMapping(value = "tolist")
    public ModelAndView tolist(ModelMap map) {
        return new ModelAndView("/security/logs/logs");
    }

    /**
     * @param page 页数
     * @param rows 每页的数据量
     * @param searchvalue  搜索关键字
     * @param order  排序
     * @param sort  按。。顺序排 ,desc、asc
     * @param starttime 开始时间
     * @param endtime  结束时间
     * @param response 相应信息
     * @return
     */
    @RequestMapping(value = "list")
    @ResponseBody
    public Object list(Integer page, Integer rows, String searchvalue,
            String order, String sort, String starttime, String endtime,
            HttpServletResponse response) {
        String value = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // ----非空判断----
        if (StringUtils.isNotEmpty(searchvalue)) {
            try {
                value = URLDecoder.decode(searchvalue, "UTF-8");
            } catch (UnsupportedEncodingException e1) {
                e1.printStackTrace();
            }
        }
        Date st = null;
        Date et = null;
        if (StringUtils.isNotEmpty(starttime)) {
            try {
                st = sdf.parse(starttime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        if (StringUtils.isNoneEmpty(endtime)) {
            try {
                et = sdf.parse(endtime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        // ---获取到登录账户的ID值
        Subject currentUser = SecurityUtils.getSubject();
        String userId = currentUser.getSession().getAttribute("_USER_ID")
                .toString();
        PageInfo pageInfo = new PageInfo(page, rows);
        Map condition = new HashMap();
        int start = (page - 1) * rows;
        int end = start + rows;
        condition.put("st", st);// 开始时间
        condition.put("et", et);// 结束时间
        condition.put("start", start);
        condition.put("end", end);
        condition.put("order", order);// 为空没有使用
        condition.put("sort", sort);// 为空没有使用
        condition.put("value", value);// 获取到搜索框的值(字符)
        condition.put("userId", userId);
        condition.put("searchvalue", searchvalue);
        pageInfo.setCondition(condition);
        systemLogService.findLogs(pageInfo);
        return pageInfo;
    }

}

systemLogMapper.xml

三个方法:

//插入到数据库

 
   
    insert into CMU_SYSTEM_LOG
   
     
        LOG_ID,
     

     
        USER_ID,
     

     
        USERNAME,
     

     
        DESCRIPTION,
     

     
        METHODS,
     

     
        LOG_TYPE,
     

     
        REQUEST_IP,
     

     
        EXCEPTIONCODE,
     

     
        EXCEPTION_DETAIL,
     

     
        PARAMS,
     

     
        TIME,
     

   

   
     
        #{logId,jdbcType=DECIMAL},
     

     
        #{userId,jdbcType=DECIMAL},
     

     
        #{username,jdbcType=VARCHAR},
     

     
        #{description,jdbcType=VARCHAR},
     

     
        #{methods,jdbcType=VARCHAR},
     

     
        #{logType,jdbcType=VARCHAR},
     

     
        #{requestIp,jdbcType=DECIMAL},
     

     
        #{exceptioncode,jdbcType=VARCHAR},
     

     
        #{exceptionDetail,jdbcType=VARCHAR},
     

     
        #{params,jdbcType=VARCHAR},
     

     
        #{time,jdbcType=TIMESTAMP},
     

   

 

//查询拉取数据(并且有模糊查询和时间判断)

 

//计算数据的条数

 

最后  最重要的是给你需要插入数据库的接口增加:@SysLog(operationType="submitLogin",operationName="代理商登录")   //举例


前端jsp使用的是easyUI框架:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>





日志列表
    href="${ctx}/resources/easyui/themes/default/easyui.css">
    href="${ctx}/resources/easyui/themes/icon.css">







    


        
            style="overflow: hidden;">
            

            

            

                
            
   
            开始时间:     
            结束时间:    
            查询
            

        




最终显示:

你可能感兴趣的:(springAOP)