后台管理系统之系统操作日志开发(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拦截器记录系统操作日志
前言 最近开发了一个项目,由于项目在整个开发过程中处于赶时间状态(每个项目都差不多如此)所以项目在收尾阶段发现缺少记录系统日志功能,以前系统都是直接写在每个模块的代码中,然后存入表单,在页面可以查看部 ...
随机推荐
- Linux 小知识翻译 - 「邮件服务器」
这次聊聊「邮件服务器」. 邮件服务器上通常会运行2个服务端软件,「SMTP服务器」和「POP服务器或者IMAP服务器」. 这2个东西,也许使用邮件客户端的人立马就明白了.因为设置邮件客户端的时候,需要 ...
- February 19th, 2018 Week 8th Monday
Love is blind, hard to find, difficult to get, and impossible to forget. 爱,很盲目,很难找,很难得,很难忘. It is al ...
- Unity Shader 基础(1): RenderType & ReplacementShader
很多Shader中都会定义RenderType这个类型,但是一直搞不明白到底是干嘛的,官方文档是这样结解释的:Rendering with Replaced Shaders Rendering wit ...
- Spring的jdbc模板3:完成CURD操作
测试类代码如下 package zcc.spring_jdbc.demo2; import java.sql.ResultSet; import java.sql.SQLException; impo ...
- MySQL高级知识(四)——Explain
前言:explain(执行计划),使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句.explain主要用于分析查询语句或表结构的性能瓶颈. 注:本系列随 ...
- Zookeeper的一致性
转载:http://flyfoxs.iteye.com/blog/2121560 下面内容主要摘抄于<<Hadoop实战>>,红色高亮部分是本人添加的白话注释. Zookeep ...
- UVA1646-Edge Case(递推+斐波那契数列)
Problem UVA1646-Edge Case Time Limit: 3000 mSec Problem Description Input For each test case, you ge ...
- Python:Day45 Javascript的String字符串
typeof只能判断普通数据类型, 对于复杂的只是判断出来是一个Object: instanceof 可以判断数据是否是某一类型: alert(s instanceof String); String ...
- 【移动端】meta使用
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http ...
- 在linux中查看进程占用的端口号
在Linux 上的 /etc/services 文件可以查看到更多关于保留端口的信息. 可以使用以下六种方法查看端口信息. ss:可以用于转储套接字统计信息. netstat:可以显示打开的套接字列表 ...