SSM框架下通过AOP切面的方式创建实现日志sysLogs添加显示

通过AOP切面实现日志信息的保存

mysql日志表数据库设计
syslog 数据库设计

第一步创建SysLog实体类

package com.travel_ssm_pojo.pojo;

import com.travel_ssm_utils.utils.FormatDateUtil;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;

import java.util.Date;
@Component
public class SysLog {
    private String id;//无意义,主键 UUID

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date visitTime;//访问时间
    private String visitTimeStr;

    private String username;//操作者用户名

    private String ip;//访问IP

    private String url;//访问资源URL

    private Long executionTime;//执行时长

    private String method;//访问方法

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getVisitTime() {
        return visitTime;
    }

    public void setVisitTime(Date visitTime) {
        this.visitTime = visitTime;
    }

    public String getVisitTimeStr() {
        if (this.visitTime!=null){
            this.visitTimeStr=FormatDateUtil.dateToStrLong(this.visitTime);
        }
        return visitTimeStr;
    }

    public void setVisitTimeStr(String visitTimeStr) {
        this.visitTimeStr = visitTimeStr;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Long getExecutionTime() {
        return executionTime;
    }

    public void setExecutionTime(Long executionTime) {
        this.executionTime = executionTime;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    @Override
    public String toString() {
        return "SysLog{" +
                "id='" + id + '\'' +
                ", visitTime=" + visitTime +
                ", visitTimeStr='" + visitTimeStr + '\'' +
                ", username='" + username + '\'' +
                ", ip='" + ip + '\'' +
                ", url='" + url + '\'' +
                ", executionTime=" + executionTime +
                ", method='" + method + '\'' +
                '}';
    }
}

第二步创建SysLogDao持久层

该类采用mybatis注解的方式实现SQL语句


@Repository
public interface SysLogDao {
    /*保存日志信息*/
    @Insert("INSERT INTO syslog VALUES(#{id},#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")
    void saveSysLog(SysLog sysLog);

    /*查询所有日志信息*/
    @Select("select * from syslog")
    List<SysLog> findAllLogs();

}

第三步创建SYSLogService业务层

service接口

public interface SysLogService {
    //保存日志信息
    void saveSysLog(SysLog sysLog);
    //查看所有日志信息
    List<SysLog> findAllLogs(Integer page,Integer size);
}

serviceImpl实现类

@Service
@Transactional
public class SysLogServiceImpl implements SysLogService {
    @Autowired
    private SysLogDao logDao;
    /*保存日志信息,通过切面*/
    public void saveSysLog(SysLog sysLog) {
        logDao.saveSysLog(sysLog);
    }
    /*查询所有日志信息,分页*/
    public List<SysLog> findAllLogs(Integer page,Integer size) {
        PageHelper.startPage(page,size);
        return logDao.findAllLogs();
    }
}

第四步在springMVC.xml配置文件中开启切面注解代理

<!--开启切面-->
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

第五步在web.xml配置文件中配置request监听器

  <!--配置HttpServletRequest监听器-->
  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>

第六步创建LogAOP切面类

package com.travel_ssm_web.web.logaop;

import com.travel_ssm_pojo.pojo.SysLog;
import com.travel_ssm_service.service.SysLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.UUID;

@Component
@Aspect
public class LogAop {
    private Class executionClass;//类
    private Method executionMethod;//方法
    private Date startTime;//开始时间
    private long executionTime;//执行的时长
    private String ip;//访问IP地址
    private String username;//访问用户名


    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SysLog sysLog;
    @Autowired
    private SysLogService logService;
    /**
     * 获取方法返回时间
     * 前置通知
     */
    @Before("execution(* com.travel_ssm_web.web.*.*(..))")
    public void doBefore(JoinPoint joinPoint){
        //获取访问时间
         startTime = new Date();
        //获取访问的方法
        //第一,获取访问的类
         executionClass = joinPoint.getTarget().getClass();
        //获取访问方法的名称
        String methodName = joinPoint.getSignature().getName();
        //获取方法的参数
        Object[] args = joinPoint.getArgs();
        //判断参数是否为空,来判断是有参构造还是无参构造
        if (args==null||args.length==0){
            try {
                //通过获取的访问的类来获取方法
                 executionMethod = executionClass.getMethod(methodName);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }else {
            //不为空,为有参方法,遍历方法的 参数,获取到class类型,放入到数组中
            //定义类数组,长度为参数长度
            Class[] classes = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                classes[i]= args[i].getClass();
            }
            //通过类得到类中的方法,通过方法名和参数
            try {
               executionMethod= executionClass.getMethod(methodName,classes);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 后置通知
     * 获取对应的总访问时长,访问ip和访问URL
     */
    @After("execution(* com.travel_ssm_web.web.*.*(..))")
    public void doAfter(){
        //获取URL通过获取的注解类的requestMapping(value="")的属性来获取
        RequestMapping classMapping = (RequestMapping) executionClass.getAnnotation(RequestMapping.class);
        if (classMapping!=null){
            //获取对应方法的requestMapping的注解类
            RequestMapping methodMapping = executionMethod.getAnnotation(RequestMapping.class);
            if (methodMapping!=null){
                //获取类requestMapping中的value的属性值
                String classValue = classMapping.value()[0];
                //获取方法requestMapping中的value属性的值
                String methodValue = methodMapping.value()[0];
                String url=classValue+methodValue;
                //获取对应controller中方法的时长
                executionTime = new Date().getTime() - startTime.getTime();
                //获取IP地址
                 ip = request.getRemoteAddr();
                 //获取用户名
                SecurityContext context = SecurityContextHolder.getContext();
                User user = (User) context.getAuthentication().getPrincipal();
                username=user.getUsername();
                //生成UUID主键id
                String id = UUID.randomUUID().toString().replace("-", "");

                //保存日志信息
                sysLog.setId(id);
                sysLog.setVisitTime(startTime);
                sysLog.setUsername(username);
                sysLog.setIp(ip);
                sysLog.setUrl(url);
                sysLog.setExecutionTime(executionTime);
                sysLog.setMethod("[类名]" + executionClass.getName() + "[方法名]" +executionMethod.getName());
                //调用service方法
                logService.saveSysLog(sysLog);

            }
        }

    }

}

实现页面展示所有日志信息

controller层


@Controller
@RequestMapping("/log")
public class LogController {
    @Autowired
    private SysLogService logService;

    /**
     * 通过pageHelper实现分页查询所有日志信息
     * @param page
     * @param size
     * @return
     */
    @RequestMapping("/findall")
    public ModelAndView findAll(@RequestParam(defaultValue = "1",required = false) Integer page,@RequestParam(defaultValue = "5",required = false) Integer size){
        ModelAndView modelAndView = new ModelAndView();
        List<SysLog> allLogs = logService.findAllLogs(page,size);
        PageInfo<SysLog> pageInfo = new PageInfo<>(allLogs);
        modelAndView.addObject(pageInfo);
        modelAndView.setViewName("log-list");
        return modelAndView;
    }
}

log-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_desc">访问时间</th>
										<th class="sorting_asc sorting_asc_disabled">操作者</th>
										<th class="sorting_desc sorting_desc_disabled">访问IP</th>
										<th class="sorting">访问资源URL</th>
										<th class="text-center">执行时长</th>
										<th class="text-center">访问方法</th>
									</tr>
								</thead>
								<tbody>

									<c:forEach items="${pageInfo.list}" var="log">
										<tr>
											<td><input name="ids" type="checkbox"></td>
											<td>${log.id }</td>
											<td>${log.visitTimeStr }</td>
											<td>${log.username }</td>
											<td>${log.ip }</td>
											<td>${log.url }</td>
											<td>${log.executionTime }</td>
											<td>${log.method }</td>
										</tr>
									</c:forEach>
								</tbody>
								<!--
                            <tfoot>
                            <tr>
                            <th>Rendering engine</th>
                            <th>Browser</th>
                            <th>Platform(s)</th>
                            <th>Engine version</th>
                            <th>CSS grade</th>
                            </tr>
                            </tfoot>-->
							</table>
							<!--数据列表/-->
发布了7 篇原创文章 · 获赞 2 · 访问量 1182

猜你喜欢

转载自blog.csdn.net/weixin_41040866/article/details/105067768