一,功能点

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

二,代码实现

基于注解的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. February 22nd, 2018 Week 8th Thursday

    Confine yourself to the present. 着眼当下. The morning wind spreads its fresh smell, we should get up an ...

  2. 《生命》第二集:Reptiles and Amphibians (爬行和两栖动物)

    第二集也是一个个动物的片段,不过集中在爬行和两栖类动物上. 印度尼西亚的瀑布蟾蜍进化出神器强有力的脚,能够抓牢很多物体,是逃生的手段,同一环境下,卵石蟾蜍,能够缩紧全身肌肉,眼山坡下滑,是另一种逃生是 ...

  3. 【Linux基础】crontab定时命令详解

    周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间.cron的配置文件称为“crontab”,是 ...

  4. eshint的配置

    { "strict" : "implied", //文件里面使用"use strict" "undef" : true, ...

  5. JZOJ 5602.【NOI2018模拟3.26】Cti

    JZOJ 5602.[NOI2018模拟3.26]Cti Description 有一个 \(n×m\) 的地图,地图上的每一个位置可以是空地,炮塔或是敌人.你需要操纵炮塔消灭敌人. 对于每个炮塔都有 ...

  6. WPF 使用Console.Write打印信息到控制台窗口中

    WPF中使用Console.Write函数来打印信息是没有意义的,因为并没有给其输出字符的窗口.对于桌面程序来说,这是十分合理的,然而有时为了方便调试,在程序编写过程中打印出信息给程序员看还是必要的, ...

  7. 创建线程时如果既传入了runnable对象,又继承thread重写了run方法,会执行的哪里的代码

    1 使用线程的方式,继承thread类,重写run方法 new Thread() { @Override public void run() { System.out.println("我是 ...

  8. len()方法

    len() 方法返回对象(字符.列表.元组等)长度或项目个数 len()方法语法: len( 对象 )

  9. CONTRO4 系列

    软件下载 https://getcomposer.org/download/ 0技术手册 https://wenku.baidu.com/view/4b511ead376baf1ffd4fad36.h ...

  10. pyspider环境部署2--pyspider安装

    接上篇文章,在python3.6.4安装完成的基础上,安装相关依赖模块及pyspider. 依赖安装 1.setuptools和pip setuptools和pip是python的包管理工具,pyth ...