一,功能点

实现管理员操作数据的记录。效果如下

二,代码实现

基于注解的Aop日志记录

1.Log实体类

package com.ideal.manage.guest.bean.log;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date; /**
* @apiNote 日志
* @author Yaming
* @since 2019-01-24
*/
@Entity
@Table(name = "visitor_sys_log")
public class Log implements Serializable { private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id; private String content; private String description; private String ip; private String module; private String username; private Date createAt; private Date updateAt; private Integer able; public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} public String getIp() {
return ip;
} public void setIp(String ip) {
this.ip = ip;
} public String getModule() {
return module;
} public void setModule(String module) {
this.module = module;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public static long getSerialVersionUID() {
return serialVersionUID;
} public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public Date getCreateAt() {
return createAt;
} public void setCreateAt(Date createAt) {
this.createAt = createAt;
} public Date getUpdateAt() {
return updateAt;
} public void setUpdateAt(Date updateAt) {
this.updateAt = updateAt;
} public Integer getAble() {
return able;
} public void setAble(Integer able) {
this.able = able;
}
}

2.定义注解

package com.ideal.manage.guest.annotation;

import java.lang.annotation.*;

/**
* @author Hao
* @create 2017-03-29
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**模块*/
String module() default ""; /**描述*/
String description() default "";
}

3.定义切面

package com.ideal.manage.guest.aop;

import com.ideal.manage.guest.annotation.Log;
import com.ideal.manage.guest.service.log.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method; /**
* 日志切面处理类
*
* @author Yaming
* @create 2019-01-24
*/
@Aspect
@Component
public class LogAspect { @Autowired
private LogService logService; /**
* 日志切入点
*/
@Pointcut("@annotation(com.ideal.manage.guest.annotation.Log)")
public void logPointCut(){} @AfterReturning(pointcut = "logPointCut()")
public void doAfter(JoinPoint joinPoint){
/**
* 解析Log注解
*/
String methodName = joinPoint.getSignature().getName();
Method method = currentMethod(joinPoint,methodName);
Log log = method.getAnnotation(Log.class);
logService.put(joinPoint,methodName,log.module(),log.description());
} /**
* 获取当前执行的方法
*
* @param joinPoint 连接点
* @param methodName 方法名称
* @return 方法
*/
private Method currentMethod(JoinPoint joinPoint, String methodName) {
/**
* 获取目标类的所有方法,找到当前要执行的方法
*/
Method[] methods = joinPoint.getTarget().getClass().getMethods();
Method resultMethod = null;
for (Method method : methods) {
if (method.getName().equals(methodName)) {
resultMethod = method;
break;
}
}
return resultMethod;
} }

4.业务处理:LogService

package com.ideal.manage.guest.service.log;

import com.alibaba.fastjson.JSONObject;

import com.ideal.manage.guest.bean.DTO.PageDto;
import com.ideal.manage.guest.bean.log.Log; import com.ideal.manage.guest.config.shiro.MyShiroRealm;
import com.ideal.manage.guest.repository.framework.MySpecification;
import com.ideal.manage.guest.repository.framework.SpecificationOperator;
import com.ideal.manage.guest.repository.log.LogRepository;
import com.ideal.manage.guest.util.Const;
import com.ideal.manage.guest.util.HttpRequests;
import com.ideal.manage.guest.util.IPUtils; /*import org.apache.ibatis.javassist.*;
import org.apache.ibatis.javassist.bytecode.CodeAttribute;
import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute;
import org.apache.ibatis.javassist.bytecode.MethodInfo;*/
import javassist.*;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; /**
* <p>
* 服务实现类
* </p>
*
* @author
* @since 2017-09-05
*/
@Service
public class LogService{ private static final String LOG_CONTENT = "[类名]:%s,[方法]:%s,[参数]:%s,[IP]:%s"; private String username; @Autowired
private LogRepository logRepository; public String initUsername(String username) {
if(!StringUtils.isEmpty(username)){
this.username = username;
}
return this.username;
} public void put(JoinPoint joinPoint, String methodName, String module, String description) {
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Log log = new Log();
//username = ((JwtClient) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
// 获取当前登录用户
MyShiroRealm.ShiroUser shiroUser = (MyShiroRealm.ShiroUser) SecurityUtils.getSubject().getPrincipal();
// User user = userRepository.findOne(shiroUser.getId());
username = shiroUser.getUsername();
if (StringUtils.isEmpty(username)) {
username = Const.USERNAME_IN_CONTEXT != null ? Const.USERNAME_IN_CONTEXT : "未知用户";
} String ip = IPUtils.getIpAddr(request);
log.setUsername(username);
log.setModule(module);
log.setDescription(description);
log.setIp(ip);
log.setContent(operateContent(joinPoint, methodName, ip, request));
log.setAble(1);
//insert(log);
logRepository.save(log);
} catch (Exception e) {
e.printStackTrace();
}
} /*public Page<Log> page(LogRequest request, Page<Log> page) {
if(request == null){
request = new LogRequest();
}
request.setIsDeleted(Config.ABLE_CONFIG.ABLE);
List<Log> logs = baseMapper.page(request,page);
page.setRecords(logs);
return page;
}*/ /**
* 查询所有日志
* @param pageNum
* @param request
* @return
*/
public PageDto findAll(int pageNum, HttpServletRequest request) {
Sort sort = new Sort(Sort.Direction.DESC, "updateAt");
List<SpecificationOperator> operators = HttpRequests.getParametersStartingWith(request, "Q_");
//增加删除标识的过滤
SpecificationOperator isValid = new SpecificationOperator("able", "1", "EQ");
operators.add(isValid);
MySpecification<Log> mySpecifications = new MySpecification<>(operators);
Pageable pageable = new PageRequest(pageNum, 10, sort);
Page<Log> page = logRepository.findAll(mySpecifications, pageable);
//设置PageDto
List<Log> parameters = page.getContent();
long total = page.getTotalElements();
PageDto pageDto = new PageDto();
pageDto.setRows(parameters);
pageDto.setTotal(total);
return pageDto;
} public String operateContent(JoinPoint joinPoint, String methodName, String ip, HttpServletRequest request) throws ClassNotFoundException, NotFoundException {
String className = joinPoint.getTarget().getClass().getName();
Object[] params = joinPoint.getArgs();
String classType = joinPoint.getTarget().getClass().getName();
Class<?> clazz = Class.forName(classType);
String clazzName = clazz.getName();
Map<String,Object > nameAndArgs = getFieldsName(this.getClass(), clazzName, methodName,params);
StringBuffer bf = new StringBuffer();
if (!CollectionUtils.isEmpty(nameAndArgs)){
Iterator it = nameAndArgs.entrySet().iterator();
while (it.hasNext()){
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = JSONObject.toJSONString(entry.getValue());
bf.append(key).append("=");
bf.append(value).append("&");
}
}
if (StringUtils.isEmpty(bf.toString())){
bf.append(request.getQueryString());
}
return String.format(LOG_CONTENT, className, methodName, bf.toString(), ip);
} private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws NotFoundException {
Map<String,Object > map=new HashMap<String,Object>(); ClassPool pool = ClassPool.getDefault();
ClassClassPath classPath = new ClassClassPath(cls);
pool.insertClassPath(classPath); CtClass cc = pool.get(clazzName);
CtMethod cm = cc.getDeclaredMethod(methodName);
MethodInfo methodInfo = cm.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
if (attr == null) {
// exception
return map;
}
int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
for (int i = 0; i < cm.getParameterTypes().length; i++){
map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名
}
return map;
}
}

5.dao

package com.ideal.manage.guest.repository.log;
import com.ideal.manage.guest.bean.log.Log;
import com.ideal.manage.guest.repository.framework.BaseRepository; /**
* <p>
* Mapper 接口
* </p>
*
* @author Yankee
* @since 2017-09-05
*/ public interface LogRepository extends BaseRepository<Log,String> { /**
* 查询分页
* @param request
* @param page
* @return
*/
//List<Log> page(@Param("re") LogRequest request, Pagination page);
}

三,使用注解在需要的地方记录日志

@Log(module = "设备管理",description = "添加设备")
public Integer saveEquipment(Equipment equipment) {
equipment.setAble(1);
Equipment resultEquipment = equipmentRepository.save(equipment);
if(resultEquipment == null){
return StateUtil.RESULT_FAILED;
}
return StateUtil.RESULT_SUCCESS;
}

后台管理系统之系统操作日志开发(Java实现)的更多相关文章

  1. asp.net mvc 系统操作日志设计

    第一步.系统登录日志 通过signalr来管理用户的登录情况,并保存用户的登录记录. 第二步 通过mvc过滤器,来横切路由访问记录. 保存方式:通过httpclient异步请求webapi 数据通过m ...

  2. 后台管理系统之系统运行日志开发(Java实现)

    一,实现运行日志记录在文件中,并实现日志分包记录,项目出问题后方便定位分析.效果如图: 二,代码实现(springboot项目) 只需要在resources目录下新建:logback-spring.x ...

  3. springboot—spring aop 实现系统操作日志记录存储到数据库

    原文:https://www.jianshu.com/p/d0bbdf1974bd 采用方案: 使用spring 的 aop 技术切到自定义注解上,针对不同注解标志进行参数解析,记录日志 缺点是要针对 ...

  4. 033 SSM综合练习09--数据后台管理系统--基于AOP的日志处理

    1.数据库与表结构 (1)日志表信息描述sysLog (2)Sql语句 CREATE TABLE sysLog ( id ) DEFAULT SYS_GUID () PRIMARY KEY, visi ...

  5. 030 SSM综合练习06--数据后台管理系统--SSM权限操作及Spring Security入门

    1.权限操作涉及的三张表 (1)用户表信息描述users sql语句: CREATE TABLE users ( id ) DEFAULT SYS_GUID () PRIMARY KEY, email ...

  6. 028 SSM综合练习04--数据后台管理系统--订单相关操作

    1.订单表及其关联表的关系分析 2.数据库表对应实体类 (1)Orders.java package lucky.domain; import lucky.utils.DateUtils; impor ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统--任务调度系统解析

    1.任务主界面.任务可以被挂起,启动,和删除.来自著名Quartz扩展 2.任务可以是执行的SQL命令,存储过程,或者是一个后台方法 3.极其复杂的调度任务,循环次数,可以自行设置.并可以间隔执行,比 ...

  8. vue开发后台管理系统小结

    最近工作需要用vue开发了后台管理系统,由于是第一次开发后台管理系统,中间也遇到了一些坑,想在这里做个总结,也算是对于自己工作的一个肯定.我们金融性质的网站所以就不将代码贴出来哈 一.项目概述 首先工 ...

  9. Struts2拦截器记录系统操作日志

    前言 最近开发了一个项目,由于项目在整个开发过程中处于赶时间状态(每个项目都差不多如此)所以项目在收尾阶段发现缺少记录系统日志功能,以前系统都是直接写在每个模块的代码中,然后存入表单,在页面可以查看部 ...

随机推荐

  1. SSL 原理及 https 配置

    目录 1. SSL 原理 1.1. SSL 简介 1.2. 主要概念 1.3. 建立安全连接的过程 2. https 配置 (以 nginx 为例) SSL 原理 SSL 简介 SSL (Secure ...

  2. SpringCloud之初识Feign ----- 分布式负载自动拼接请求的URL

    在前面的学习中,我们使用了Ribbon的负载均衡功能,大大简化了远程调用时的代码: String baseUrl = "http://user-service/user/"; Us ...

  3. Spring 的application.properties项目配置与注解

    一.项目结构介绍 如上图所示,Spring Boot的基础结构共三个文件: src/main/java  程序开发以及主程序入口 src/main/resources 配置文件 src/test/ja ...

  4. RPC入门总结(一)RPC定义和原理

    转载:深入浅出 RPC - 浅出篇 转载:RPC框架与Dubbo完整使用 转载:深入浅出 RPC - 深入篇 转载:远程调用服务(RPC)和消息队列(Message Queue)对比及其适用/不适用场 ...

  5. 【JSOI2018】潜入行动

    [JSOI2018]潜入行动 树形\(DP\).设\(f_{i,j,0/1,0/1}\)表示以\(i\)为根的子树中,用了\(j\)个监听器,是否放置了监听器,是否被监听的方案数.转移就多讨论几种情况 ...

  6. 设计模式のChainOfResponsibilityPattern(责任链模式)----行为模式

    一.产生背景 职责链模式是一种行为模式,为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求.将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对象处理它.避免请求发送者与接 ...

  7. Python实现矿池

    自建P2POOL矿池详细教程(高级篇)http://8btc.com/article-1804-1.html p2pool比特币矿池教程综合篇(包含linux矿池教程)https://www.cybt ...

  8. Linux之定时任务crond

    定时任务说明与分类 定时任务的应用场景举例 每天晚上 12点备份/etc/目录 tar 定时任务的三种分类 crond(crontab)定时任务软件(软件包cronie),用的最多的一种 atd,应用 ...

  9. java爬虫代理

    public static Document getDocByJsoups(String href) { String ip = "124.47.7.38"; int port = ...

  10. 从零开始的ESP8266探索(1)-使用Server功能搭建Web Server

    https://blog.csdn.net/Naisu_kun/article/details/80398667 文件系统 https://blog.csdn.net/solar_Lan/articl ...