后台管理系统之系统操作日志开发(Java实现)
一,功能点
实现管理员操作数据的记录。效果如下
二,代码实现
基于注解的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实现)的更多相关文章
- asp.net mvc 系统操作日志设计
第一步.系统登录日志 通过signalr来管理用户的登录情况,并保存用户的登录记录. 第二步 通过mvc过滤器,来横切路由访问记录. 保存方式:通过httpclient异步请求webapi 数据通过m ...
- 后台管理系统之系统运行日志开发(Java实现)
一,实现运行日志记录在文件中,并实现日志分包记录,项目出问题后方便定位分析.效果如图: 二,代码实现(springboot项目) 只需要在resources目录下新建:logback-spring.x ...
- springboot—spring aop 实现系统操作日志记录存储到数据库
原文:https://www.jianshu.com/p/d0bbdf1974bd 采用方案: 使用spring 的 aop 技术切到自定义注解上,针对不同注解标志进行参数解析,记录日志 缺点是要针对 ...
- 033 SSM综合练习09--数据后台管理系统--基于AOP的日志处理
1.数据库与表结构 (1)日志表信息描述sysLog (2)Sql语句 CREATE TABLE sysLog ( id ) DEFAULT SYS_GUID () PRIMARY KEY, visi ...
- 030 SSM综合练习06--数据后台管理系统--SSM权限操作及Spring Security入门
1.权限操作涉及的三张表 (1)用户表信息描述users sql语句: CREATE TABLE users ( id ) DEFAULT SYS_GUID () PRIMARY KEY, email ...
- 028 SSM综合练习04--数据后台管理系统--订单相关操作
1.订单表及其关联表的关系分析 2.数据库表对应实体类 (1)Orders.java package lucky.domain; import lucky.utils.DateUtils; impor ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统--任务调度系统解析
1.任务主界面.任务可以被挂起,启动,和删除.来自著名Quartz扩展 2.任务可以是执行的SQL命令,存储过程,或者是一个后台方法 3.极其复杂的调度任务,循环次数,可以自行设置.并可以间隔执行,比 ...
- vue开发后台管理系统小结
最近工作需要用vue开发了后台管理系统,由于是第一次开发后台管理系统,中间也遇到了一些坑,想在这里做个总结,也算是对于自己工作的一个肯定.我们金融性质的网站所以就不将代码贴出来哈 一.项目概述 首先工 ...
- Struts2拦截器记录系统操作日志
前言 最近开发了一个项目,由于项目在整个开发过程中处于赶时间状态(每个项目都差不多如此)所以项目在收尾阶段发现缺少记录系统日志功能,以前系统都是直接写在每个模块的代码中,然后存入表单,在页面可以查看部 ...
随机推荐
- SSL 原理及 https 配置
目录 1. SSL 原理 1.1. SSL 简介 1.2. 主要概念 1.3. 建立安全连接的过程 2. https 配置 (以 nginx 为例) SSL 原理 SSL 简介 SSL (Secure ...
- SpringCloud之初识Feign ----- 分布式负载自动拼接请求的URL
在前面的学习中,我们使用了Ribbon的负载均衡功能,大大简化了远程调用时的代码: String baseUrl = "http://user-service/user/"; Us ...
- Spring 的application.properties项目配置与注解
一.项目结构介绍 如上图所示,Spring Boot的基础结构共三个文件: src/main/java 程序开发以及主程序入口 src/main/resources 配置文件 src/test/ja ...
- RPC入门总结(一)RPC定义和原理
转载:深入浅出 RPC - 浅出篇 转载:RPC框架与Dubbo完整使用 转载:深入浅出 RPC - 深入篇 转载:远程调用服务(RPC)和消息队列(Message Queue)对比及其适用/不适用场 ...
- 【JSOI2018】潜入行动
[JSOI2018]潜入行动 树形\(DP\).设\(f_{i,j,0/1,0/1}\)表示以\(i\)为根的子树中,用了\(j\)个监听器,是否放置了监听器,是否被监听的方案数.转移就多讨论几种情况 ...
- 设计模式のChainOfResponsibilityPattern(责任链模式)----行为模式
一.产生背景 职责链模式是一种行为模式,为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求.将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对象处理它.避免请求发送者与接 ...
- Python实现矿池
自建P2POOL矿池详细教程(高级篇)http://8btc.com/article-1804-1.html p2pool比特币矿池教程综合篇(包含linux矿池教程)https://www.cybt ...
- Linux之定时任务crond
定时任务说明与分类 定时任务的应用场景举例 每天晚上 12点备份/etc/目录 tar 定时任务的三种分类 crond(crontab)定时任务软件(软件包cronie),用的最多的一种 atd,应用 ...
- java爬虫代理
public static Document getDocByJsoups(String href) { String ip = "124.47.7.38"; int port = ...
- 从零开始的ESP8266探索(1)-使用Server功能搭建Web Server
https://blog.csdn.net/Naisu_kun/article/details/80398667 文件系统 https://blog.csdn.net/solar_Lan/articl ...