企业权限管理系统第6章--AOP日志

本章简介

  • 基于Spring AOP对每次请求进行记录

数据库、表结构与实体类

日志表sysLog信息描述

在这里插入图片描述

创建表和插入数据的sql语句

CREATE TABLE sysLog(
id VARCHAR2(32) default SYS_GUID() PRIMARY KEY,
visitTime timestamp,
username VARCHAR2(50),
ip VARCHAR2(30),
url VARCHAR2(50),
executionTime int,
method VARCHAR2(200)
)

SysLog实体类

public class SysLog {
    private String id;
    private Date visitTime;
    private String visitTimeStr;
    private String username;
    private String ip;
    private String url;
    private Long executionTime;
    private String method;
}

基于AOP完成日志处理

创建LogAop切面类处理日志

在切面类中需要获取的内容包括:

  • 访问用户的username
  • 访问时间
  • 访问的类
  • 访问的方法
  • 请求发出到返回数据的执行时间
  • ip地址
  • 资源URL
  • 访问用户

LogAop类简介:

  • 在com.cncs.controller中创建这个类

  • 使用@Component标识它被Spring管理,使用@Aspect标识它是一个切面类

  • HttpServletRequest属性用于获取用户ip

  • doBefore()中记录访问的类,方法和时间。

  • doAfter()中记录执行时间,访问的ip,访问的用户,访问的资源URL。

@Component
@Aspect
public class LogAop {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ISysLogService sysLogService;

    private Date visitTime;//访问时间
    private Class executionClass;//访问的类
    private Method executionMethod;//访问的方法

    @Pointcut("execution(* com.cncs.controller.*.*(..)) && !execution(* com.cncs.controller.SysLogController.*(..))")//自定义切入点,不处理sysLogController类
    public void pt1(){};

    //获取访问的类,访问的方法,访问的时间
    @Before("pt1()")//记录所有controller访问过程
    public void doBefore(JoinPoint jp) throws NoSuchMethodException {
        visitTime = new Date();//访问时间
        executionClass = jp.getTarget().getClass();//访问的类
        //获取访问的方法
        String methodName = jp.getSignature().getName();//访问的方法名
        Object[] args = jp.getArgs();//访问的方法的参数
        if (args == null || args.length == 0) {//无参数
            executionMethod = executionClass.getMethod(methodName);
        } else {
            //有参数,将args中所有元素遍历,获取对应的class,装入到一个Class[]
            Class[] classArgs = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                classArgs[i] = args[i].getClass();
            }
            executionMethod = executionClass.getMethod(methodName, classArgs);//获取有参数的方法
        }
    }

    //获取执行的时间,访问的用户名称,用户ip,访问的url,
    @After("pt1()")
    public void doAfter() {
        //执行的时间
        long executionTime = new Date().getTime() - visitTime.getTime();
        //用户访问的url
        String url = "";
        if (executionClass != LogAop.class) {
            //获取controller上的@RequestMapping("/product")
            RequestMapping classAnnotation = (RequestMapping) executionClass.getAnnotation(RequestMapping.class);
            if (classAnnotation != null) {
                //获取方法上的@RequestMapping("/findAll.do")
                RequestMapping methodAnnotation = executionMethod.getAnnotation(RequestMapping.class);
                if (methodAnnotation != null) {
                    String[] classValues = classAnnotation.value();//获取controller类参数数组
                    String[] methodValues = methodAnnotation.value();//获取方法参数数组
                    url = classValues[0] + methodValues[0];
                }
            }
        }
        //用户ip
        String ip = request.getRemoteAddr();
        //用户名称
        SecurityContext securityContext = SecurityContextHolder.getContext();
        String username = ((User) (securityContext.getAuthentication().getPrincipal())).getUsername();//也可以通过request.getSession().getAttribute("SPRING_SECURITY_CONTEXT")获取
        //封装SysLog
        SysLog sysLog = new SysLog();
        sysLog.setVisitTime(visitTime);
        sysLog.setExecutionTime(executionTime);
        sysLog.setIp(ip);
        sysLog.setMethod("[类名]"+executionClass.getName()+"[方法名]"+executionMethod.getName());
        sysLog.setUsername(username);
        sysLog.setUrl(url);
        //存入数据库
        sysLogService.save(sysLog);
    }
}

要对SysAop完成HttpServletRequest的注入,需要在web.xml中添加配置:

<!-- 配置监听器,监听request域对象的创建和销毁的 -->
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

保存日志

  • 在SysAop的doAfter()中保存日志时调用service层。

部分代码

SysLogService

@Override
public void save(SysLog sysLog) {
    sysLogDao.save(sysLog);
}

SysLogDao

@Insert("insert into syslog(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")
public void save(SysLog sysLog);

查看日志

部分代码

SysLogController

@RequestMapping("/findAll.do")
public ModelAndView findAll(@RequestParam(name = "page", required = true,defaultValue = "1") Integer page,@RequestParam(name = "size",required = true,defaultValue = "4") Integer size){
    ModelAndView mv = new ModelAndView();
    List<SysLog> sysLogs =  sysLogService.findAll(page,size);
    PageInfo pageInfo = new PageInfo(sysLogs,5);//页码数量为5
    //pageInfo.setList(sysLogs);
    mv.addObject("pageInfo",pageInfo);
    mv.setViewName("syslog-list-page");
    return mv;
}

SysLogService

@Override
public List<SysLog> findAll(int page, int size) {
    PageHelper.startPage(page, size);
    return sysLogDao.findAll();
}

SysLogDao

@Select("select * from sysLog")
List<SysLog> findAll();

syslog-list.jsp

<table id="dataList"
       class="table table-bordered table-striped table-hover dataTable">
    <thead>
    <tr>
        <th class="" style="padding-right: 0px"><input id="selall"
                                                       type="checkbox"
                                                       class="icheckbox_square-blue"></th>
        <th class="sorting_asc">ID</th>
        <th class="sorting">访问时间</th>
        <th class="sorting">访问用户</th>
        <th class="sorting">访问IP</th>
        <th class="sorting">资源URL</th>
        <th class="sorting">执行时间</th>
        <th class="sorting">访问方法</th>
    </tr>
    </thead>
    <tbody>
    <c:forEach items="${pageInfo.list}" var="syslog">
        <tr>
            <td><input name="ids" type="checkbox"></td>
            <td>${syslog.id}</td>
            <td>${syslog.visitTimeStr }</td>
            <td>${syslog.username }</td>
            <td>${syslog.ip }</td>
            <td>${syslog.url}</td>
            <td>${syslog.executionTime}毫秒</td>
            <td>${syslog.method}</td>
        </tr>
    </c:forEach>
    </tbody>

</table>

<!--............-->

<div class="box-footer">
                    <div class="pull-left">
                        <div class="form-group form-inline">
                            总共${pageInfo.pages}页,共${pageInfo.total}条数据。 每页
                            <select class="form-control" id="choosePageSize" onchange="changePageSize()">
                                <option>5</option>
                                <option>6</option>
                                <option>7</option>
                                <option>8</option>
                                <option>9</option>
                            </select></div>
                    </div>

                    <div class="box-tools pull-right">
                        <ul class="pagination">
                            <li><a href="${pageContext.request.contextPath}/sysLog/findAll.do?page=${pageInfo.navigateFirstPage}&size=${pageInfo.pageSize}" aria-label="Previous">首页</a></li>
                            <li><a href="${pageContext.request.contextPath}/sysLog/findAll.do?page=${pageInfo.lastPage}&size=${pageInfo.pageSize}">上一页</a></li>
                            <c:forEach begin="1" end="${pageInfo.navigatePages}" varStatus="page">
                                <li>
                                    <a href="${pageContext.request.contextPath}/sysLog/findAll.do?page=${page.index}&size=${pageInfo.pageSize}">
                                            ${page.index}
                                    </a>
                                </li>
                            </c:forEach>
                            <li><a href="${pageContext.request.contextPath}/sysLog/findAll.do?page=${pageInfo.nextPage}&size=${pageInfo.pageSize}">下一页</a></li>
                            <li><a href="${pageContext.request.contextPath}/sysLog/findAll.do?page=${pageInfo.lastPage}&size=${pageInfo.pageSize}" aria-label="Next">尾页</a></li>
                        </ul>
                    </div>
                </div>

    // 改变每页显示条数
    function changePageSize() {
        var pageSize = $("#choosePageSize").val();
        location.href = "${pageContext.request.contextPath}/sysLog/findAll.do?page=1&size=" + pageSize;
    }

查看日志效果展示

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值