saas-export项目-系统日志管理-系统日志AOP配置

功能需求:用户在saas-export项目中使用了什么方法,进行了什么操作,都要记录在日志中,然后在日志管理页面可以查看得到。

功能分析

两个功能,一个是分页显示,一个是保存日志

在这里插入图片描述

在这里插入图片描述

系统日志管理

  • (1)分析
    记录用户的访问的Controller与ip等信息
    属于监控功能
    在这里插入图片描述

只要查看与保存功能

  • (2)数据组成
    • 设置登录用户信息 seesion获取
    • 设置企业信息
    • IP地址 request获取
    • 设置记录时间
    • 执行的方法名称 新方法获取
    • 执行的类名称

在这里插入图片描述

SysLog

public class SysLog {
    private String id            ;
    private String userName      ;
    private String ip            ;
    private Date time          ;
    private String method        ;
    private String action        ;
    private String companyId     ;
    private String companyName   ;

TestSysLogService

  • 分页查询
  • 添加
package com.lbl.service.system.syslog.impl;

import com.github.pagehelper.PageInfo;
import com.lbl.domain.system.syslog.SysLog;
import com.lbl.service.system.syslog.ISysLogService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Date;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:spring/applicationContext-*.xml")
@Slf4j
public class SysLogServiceImplTest {
    @Autowired
    ISysLogService iSysLogService;
    //增*删改查*

    @Test
    public void test01(){
        //分页列表
        //页面上显示分页列表,就要求业务方法中提供查询PageInfo的方法
        PageInfo<SysLog> pi= iSysLogService.findByPage(1,5,"1");
        log.info("pi = "+pi);
    }


    @Test
    public void test02(){

        //将一个表单数据保存在javaBean中,再将javaBean存到数据库
        SysLog sysLog = new SysLog();
        //设置登录用户信息
        sysLog.setUserName("李柏霖");
        //设置企业信息
        sysLog.setCompanyId("1");
        sysLog.setCompanyName("吉首大学");
        //IP地址
        sysLog.setIp("192.168.21.99");
        //设置记录时间
        sysLog.setTime(new Date());
        //执行的方法名称
        sysLog.setMethod("toList");
        //执行的类名称
        sysLog.setAction("com.lbl.web.company.CompanyController");

        sysLog.setCompanyId("1");
        sysLog.setCompanyName("吉首大学");
        iSysLogService.saveSysLog(sysLog);

    }


}

ISysLogService

public interface ISysLogService {
    PageInfo<SysLog> findByPage(int curr, int pageSize, String companyId);
    void saveSysLog(SysLog sysLog);
}

SysLogServiceImpl

/**
 * Created by 李柏霖
 * 2020/11/7 20:33
 */

package com.lbl.service.system.syslog.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lbl.dao.system.syslog.ISysLogDao;
import com.lbl.domain.system.syslog.SysLog;
import com.lbl.service.system.syslog.ISysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

@Service
public class SysLogServiceImpl implements ISysLogService {
    //service调用dao
    @Autowired
    ISysLogDao iSysLogDao;
    @Override
    public PageInfo<SysLog> findByPage(int curr, int pageSize, String companyId) {
        //设置参数
        PageHelper.startPage(curr,pageSize);
        //调用全查
        List<SysLog> list = iSysLogDao.findAll(companyId);
        //包装成PageInfo
        PageInfo<SysLog> pi = new PageInfo<>(list);


        return pi;
    }

    @Override
    public void saveSysLog(SysLog sysLog) {
        String uuid= UUID.randomUUID().toString();
        sysLog.setId(uuid);
        iSysLogDao.save(sysLog);
    }
}

ISysLogDao

public interface ISysLogDao {
    List<SysLog> findAll(String companyId);
    void save(SysLog sysLog);
}

ISysLogDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<!--namespace: 需要映射的Dao接口类型-->
<mapper namespace="com.lbl.dao.system.syslog.ISysLogDao">
    <!-- 配置映射 字段-->
    <resultMap id="syslogMap" type="sysLog">
        <id column="id"           property="id"          />
        <result column="user_name"    property="userName"    />
        <result column="ip"           property="ip"          />
        <result column="time"         property="time"        />
        <result column="method"       property="method"      />
        <result column="ACTION"       property="action"      />
        <result column="company_id"   property="companyId"   />
        <result column="company_name" property="companyName" />
    </resultMap>
    <!--    List<SysLog> findAll(String companyId);-->
    <select id="findAll" parameterType="string" resultMap="syslogMap">
        select * from st_sys_log where company_id =#{companyId} order by time desc
    </select>
    <!--    void save(SysLog sysLog);-->
    <insert id="save" parameterType="sysLog">
    insert into st_sys_log
        (
        id            ,
        user_name     ,
        ip            ,
        time          ,
        method        ,
        ACTION        ,
        company_id    ,
        company_name
        )
        values
        (
        #{id            },
        #{userName      },
        #{ip            },
        #{time          },
        #{method        },
        #{action        },
        #{companyId     },
        #{companyName   }
        )
    </insert>
</mapper>

SysLogController

/**
 * Created by 李柏霖
 * 2020/11/7 20:47
 */

package com.lbl.web.controller.system.syslog;


import com.github.pagehelper.PageInfo;
import com.lbl.domain.system.syslog.SysLog;
import com.lbl.service.system.syslog.ISysLogService;
import com.lbl.web.controller.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/system/syslog")
@Slf4j
public class SysLogController extends BaseController {

    @Autowired
    ISysLogService iSysLogService;



    @RequestMapping(path = "/toList.do", method = {RequestMethod.GET, RequestMethod.POST})
    public String toList(Model model, @RequestParam(defaultValue = "1") int curr, @RequestParam(defaultValue = "5") int pageSize) {
        //调查询分页列表的方法
        PageInfo<SysLog> pi = iSysLogService.findByPage(curr, pageSize, getLoginCompanyId());
        //将pi添加到页面
        request.setAttribute("pi", pi);
        model.addAttribute("pageSize",pageSize);
        return "system/syslog/log-list";
    }
}

log-list.jsp


 <c:forEach items="${pi.list}" var="log"  varStatus="st">
                        <tr>
                            <td>${st.count }</td>
                            <td>${log.userName }</td>
                            <td>${log.ip}</td>
                            <td>${log.time}</td>
                            <td>${log.action}.${log.method}</td>

                        </tr>
                    </c:forEach>

系统日志管理 优化日志列表

  • (1)分析
    日志记录多,生成的页号按钮多
  • (2)实现
    控制循环次数
    并进行边界判断

在这里插入图片描述
在这里插入图片描述

<c:forEach begin="${pi.pageNum-5 <= 0 ? 1:pi.pageNum-5 }" end="${pi.pageNum+5>pi.pages?pi.pages:pi.pageNum+5}"
                   var="i">
            <li class="paginate_button ${pi.pageNum==i ? 'active':''}"><a href="javascript:goPage(${i})">${i}</a></li>
        </c:forEach>

优化

在这里插入图片描述

我这边后面还进行了优化,就是分两种情况.

当pageNum<=5时,且pi.pageNum+5>pi.pages时end=10

当pageNum>5时,且pi.pageNum+5>pi.pages时end=pi.pageNum+5

<c:if test="${pi.pageNum<=5}">
    <c:forEach begin="${pi.pageNum-5 <= 0 ? 1:pi.pageNum-5 }" end="${pi.pageNum+5>pi.pages?pi.pages:10}"
               var="i">
        <li class="paginate_button ${pi.pageNum==i ? 'active':''}"><a href="javascript:goPage(${i})">${i}</a></li>
    </c:forEach>
</c:if>

<c:if test="${pi.pageNum>5}">
<c:forEach begin="${pi.pageNum-4 <= 0 ? 1:pi.pageNum-4 }" end="${pi.pageNum+5>pi.pages?pi.pages:pi.pageNum+5}"
           var="i">
    <li class="paginate_button ${pi.pageNum==i ? 'active':''}"><a href="javascript:goPage(${i})">${i}</a></li>
</c:forEach>
</c:if>

优化版

        <c:choose>
            <c:when test="${pi.pages>10}">
                <c:if test="${pi.pageNum<=5}">
                    <c:forEach begin="${pi.pageNum-5 <= 0 ? 1:pi.pageNum-5 }" end="${pi.pageNum+5>pi.pages?pi.pages:10}"
                               var="i">
                        <li class="paginate_button ${pi.pageNum==i ? 'active':''}"><a href="javascript:goPage(${i})">${i}</a></li>
                    </c:forEach>
                </c:if>
                <c:if test="${pi.pageNum>5}">
                    <c:forEach begin="${pi.pageNum-4 <= 0 ? 1:pi.pageNum-4 }" end="${pi.pageNum+5>pi.pages?pi.pages:pi.pageNum+5}"
                               var="i">
                        <li class="paginate_button ${pi.pageNum==i ? 'active':''}"><a href="javascript:goPage(${i})">${i}</a></li>
                    </c:forEach>
                </c:if>
            </c:when>

            <c:when test="${pi.pages<10}">
                    <c:forEach begin="${pi.pageNum-4 <= 0 ? 1:pi.pageNum-4 }" end="${pi.pageNum+5>pi.pages?pi.pages:pi.pages}"
                               var="i">
                        <li class="paginate_button ${pi.pageNum==i ? 'active':''}"><a href="javascript:goPage(${i})">${i}</a></li>
                    </c:forEach>
            </c:when>
        </c:choose>

Aop记录日志

  • (1)什么是AOP
    AOP ,Aspect Oritentd Programing 面向切面编程
    本质就是在不改变代码的基础上生成动态代理类(新类)
  • (2)应用场景
    》日志记录:
    》事务管理
    》权限管理
    》性能数据记录

在这里插入图片描述

Aop记录日志

  • (1)实现步骤
  1. 编写springmvc.xml, 开启Aop自动代理
  2. 编写日志切面类(@Aspect)
  3. 测试Aop,自动记录日志。
  • (2)实现
    LogAspect

1. 编写日志切面类(@Aspect)

/**
 * Created by 李柏霖
 * 2020/11/8 19:30
 */

package com.lbl.web.utils;


import com.lbl.domain.system.syslog.SysLog;
import com.lbl.domain.system.user.User;
import com.lbl.service.system.syslog.ISysLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;

//第一步:编写切面类
@Aspect  //配置了aop逻辑
@Component //非Controller,Service Repository
@Slf4j
public class LogAspect {

    public LogAspect() {
        log.info("LogAspect 无参构造方法执行");
    }

    //要对所有的Controller的方法进行配置
    //指定包名 controller 下以及它的所有子包
    //
    @Around(value = "execution(* com.lbl.web.controller..*.*Controller.*(..))")
    public Object writeLog(ProceedingJoinPoint jp) {//切点
        // jp表示Controller中的任意方法 toList toAdd toUpdate add update delete
        //逻辑
        Object result = null;//返回一个表示页面的字符串,也可通是json数据
        try {
            //前置
            result = jp.proceed();//执行
            //后置
            //保存日志
            log.info("切面:writeLog");
            saveSysLog(jp);
        } catch (Throwable e) {
            //异常
        } finally {
            //最终
        }
        return result;
    }

    @Autowired
    ISysLogService iSysLogService;

    //登录成功之后session中是保存一个user对象的
    @Autowired
    HttpSession session;

    //request对象可以直接获取对方浏览器的IP
    @Autowired
    HttpServletRequest request;

    private void saveSysLog(ProceedingJoinPoint jp) {
        //将一个表单数据保存在javaBean中,再将javaBean存到数据库
        SysLog sysLog = new SysLog();

        User user = (User) session.getAttribute("loginUser");
        if (user != null) {
            //设置登录用户信息
            sysLog.setUserName(user.getUserName());
            //设置企业信息
            sysLog.setCompanyId(user.getCompanyId());
            sysLog.setCompanyName(user.getCompanyName());
        }

        //IP地址  request.getLocalAddr()获取请求中的ip地址
        sysLog.setIp(request.getLocalAddr());
        //设置记录时间
        sysLog.setTime(new Date());

        //执行的方法名称  jp.getSignature() 当前执行的方法 toList
        sysLog.setMethod(jp.getSignature().getName());

        //执行的类名称 jp.getTarget()目标对象
        sysLog.setAction(jp.getTarget().getClass().getName());

        log.info("saveSysLog sysLog " + sysLog);
        iSysLogService.saveSysLog(sysLog);
    }
}

2.编写springmvc.xml, 开启Aop自动代理

<!--开启AOP切面注解: 整个项目扫描有没有@Aspect注解-->
    <aop:aspectj-autoproxy/>

如果标签报错,需要添加aop的标签声明,重新打一遍<aop:aspectj-autoproxy/>就可以了,IDEA会自动加上aop的标签声明。

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值