AOP 实现日志
package com.foen.foensys.config; import com.alibaba.fastjson.JSON;
import com.foen.foensys.model.SysLogsOper;
import com.foen.foensys.model.Users;
import com.foen.foensys.service.SysLogsOperService;
import com.foen.foensys.controller.admin.BaseController;
import com.foen.foensys.utils.DateUtils;
import com.foen.foensys.utils.Utils;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map; /**
* AOP
* @auther: 作者 gzh
* @description: 类说明
* @Date: created in 15:33 2019/7/5
*/
@Order(value=1)//多个切面 ,第一个切面,
@Component
@Aspect
public class SystemLogsOperAopAction { private static final Logger logger = LoggerFactory.getLogger(SystemLogsOperAopAction.class); private long startTimeMillis = 0; // 开始时间
private long endTimeMillis = 0; // 结束时间
private long responseTime =0;
private String userId="-";
private String userName="-";
private String module;//执行模块
private String method;//执行方法
private String ip; //请求IP
private String remark; //执行备注
private String port;//端口
private String path;//操作路径
private String param;//参数
private Map<String, Object> outputParamMap = null; // 存放输出结果 @Autowired
private SysLogsOperService sysLogsOperService; /**
* 00配置接入点:定义一个切入点
* execution(* com.foen.foensys.controller..*.*(..))") "*" 第一个* 任何返回值
*/
@Pointcut("execution(@com.foen.foensys.config.SystemLogs * *(..))")
private void controllerAspect(){
logger.info("==》 Controller Log SystemLogs 记录!");
} /**
* 前置
* 1. 通过JoinPoint 获取通知的签名信息,如目标方法名,目标方法参数信息等
* @param joinPoint
*/
@Before(value = "controllerAspect() && @annotation(systemLogs)")
public void doAccessCheck(JoinPoint joinPoint,SystemLogs systemLogs){
startTimeMillis = System.currentTimeMillis();
logger.info("==>:前置通知,开始时间:"+ DateUtils.dateToStringDetail(new Date(startTimeMillis)));
} /**
* 04. 后置最终通知(目标方法只要执行完了就会执行后置通知方法)
*/
@After("controllerAspect()")
public void after(JoinPoint joinPoint){
endTimeMillis = System.currentTimeMillis();
logger.info("==>:最终通知,时间"+DateUtils.dateToStringDetail(new Date(endTimeMillis)));
responseTime = endTimeMillis - startTimeMillis;
this.saveLog();
} /**
* 环绕通知(之前前置,之后,后置通知,最终通知,整个生命周期都包括了)
* @param proceedingJoinPoint 目标对象
* @param systemLogs 自定义的注解,Around必须这样写,否则自定义的注解无法传入
* @return Object
* @throws Throwable
*/
@Around("controllerAspect() && @annotation(systemLogs)")
public Object around(ProceedingJoinPoint proceedingJoinPoint,SystemLogs systemLogs) throws Throwable {
/**
* 1.获取request信息
* 2.根据request获取session
* 3.从session中取出登录用户信息
*/
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
Users user = (Users) request.getSession().getAttribute("user");
if(user!=null){
userId =""+user.getId();
if(StringUtils.isBlank(userId)){
userId="-";
}
userName = user.getUsername();
if(StringUtils.isBlank(userName)){
userName="-";
}
}
ip = request.getRemoteAddr();
port = Utils.getLocalPort();
path = request.getRequestURI();
param = request.getParameterMap().toString();
method = systemLogs.methods();
if(StringUtils.isBlank(method)){
method = "-";
}
module = systemLogs.module();
if(StringUtils.isBlank(module)){
module = "-";
}
outputParamMap = new HashMap<String,Object>();
param = getMyParam(request); // 拦截的实体类,就是当前正在执行的controller
Object target = proceedingJoinPoint.getTarget();
// 拦截的方法名称。当前正在执行的方法
String methodName = proceedingJoinPoint.getSignature().getName();
// 拦截的方法参数
Object[] args = proceedingJoinPoint.getArgs();
// 拦截的放参数类型
Signature sig = proceedingJoinPoint.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes(); Object object = null;
// 获得被拦截的方法
Method method = null;
try {
method = target.getClass().getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
} // 判断是否包含自定义的注解,说明一下这里的SystemLog就是我自己自定义的注解
if (null != method) {
if (method.isAnnotationPresent(SystemLogs.class)) {
try {
object = proceedingJoinPoint.proceed();
remark="执行成功";
} catch (Throwable e) {
e.printStackTrace();
remark="执行异常";
}
} else {
logger.info("==>没有包含注解");
object = proceedingJoinPoint.proceed();
remark="没有包含注解";
}
} else {
logger.info("==>不需要拦截直接执行");
object = proceedingJoinPoint.proceed();
}
outputParamMap.put("result",object);
logger.info("==> 退出 环绕通知! object:"+object);
return object;
} /**
* 取参数
* @param request
* @return String
*/
private String getMyParam(HttpServletRequest request) {
Map<?,?> inputParamMap = request.getParameterMap() ; // 传入参数
Enumeration<String> enumerations=request.getParameterNames();
Map<String,Object> parameterMaps= Maps.newHashMap();
while(enumerations.hasMoreElements()){
String parameter=enumerations.nextElement();
parameterMaps.put(parameter,request.getParameter(parameter));
}
return JSON.toJSONString(parameterMaps);
} /**
*
* @param joinPoint
* @return
*/
private static String getRemark(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SystemLogs systemLogs = method
.getAnnotation(SystemLogs.class);
String remark = systemLogs.methods();
return remark;
} /**
* 输出日志
*/
private void saveLog() {
SysLogsOper sysLogsOper = new SysLogsOper();
sysLogsOper.setIp(ip);
sysLogsOper.setPort(port);
sysLogsOper.setOperTime(DateUtils.dateToStringDetail(new Date()));
sysLogsOper.setPath(path);
sysLogsOper.setUserId(userId);
sysLogsOper.setUserName(userName);
sysLogsOper.setResponseTime(responseTime);
sysLogsOper.setParam(param);
sysLogsOper.setMethod(method);
sysLogsOper.setModule(module);
sysLogsOper.setRemark(remark);
sysLogsOperService.save(sysLogsOper);
}
}
AOP 实现日志的更多相关文章
- Spring AOP 完成日志记录
Spring AOP 完成日志记录 http://hotstrong.iteye.com/blog/1330046
- Spring AOP进行日志记录
在java开发中日志的管理有很多种.我一般会使用过滤器,或者是Spring的拦截器进行日志的处理.如果是用过滤器比较简单,只要对所有的.do提交进行拦截,然后获取action的提交路径就可以获取对每个 ...
- [置顶] 使用sping AOP 操作日志管理
记录后台操作人员的登陆.退出.进入了哪个界面.增加.删除.修改等操作 在数据库中建立一张SYSLOG表,使用Sping 的AOP实现日志管理,在Sping.xml中配置 <!-- Spring ...
- Spring AOP进行日志记录,管理
在java开发中日志的管理有很多种.我一般会使用过滤器,或者是Spring的拦截器进行日志的处理.如果是用过滤器比较简单,只要对所有的.do提交进行拦截,然后获取action的提交路径就可以获取对每个 ...
- Spring Boot 入门(五):集成 AOP 进行日志管理
本篇文章是接着 Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了 Pagehelper+MyBatis 分页 ...
- spring aop实现日志收集
概述 使用spring aop 来实现日志的统一收集功能 详细 代码下载:http://www.demodashi.com/demo/10185.html 使用spring aop 来实现日志的统一收 ...
- 自定义注解-aop实现日志记录
关于注解,平时接触的可不少,像是 @Controller.@Service.@Autowried 等等,不知道你是否有过这种疑惑,使用 @Service 注解的类成为我们的业务类,使用 @Contro ...
- AOP拦截日志类,抛异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode
AOP的日志拦截类中,抛出异常: java.lang.IllegalStateException: It is illegal to call this method if the current r ...
- 【Java分享客栈】超简洁SpringBoot使用AOP统一日志管理-纯干货干到便秘
前言 请问今天您便秘了吗?程序员坐久了真的会便秘哦,如果偶然点进了这篇小干货,就麻烦您喝杯水然后去趟厕所一边用左手托起对准嘘嘘,一边用右手滑动手机看完本篇吧. 实现 本篇AOP统一日志管理写法来源于国 ...
- 【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
一.需求分析 日志数据在很多行业中都是非常敏感的数据,它们不能删除只能保存和查看,这样日志表就会越来越大,我们不可能永远让它无限制的增长下去,必须采取一种手段将数据分散开来.假设现在整个数据库需要保存 ...
随机推荐
- (转)Linux中显示空闲内存空间的free命令的基本用法
这篇文章主要介绍了Linux系统中free命令的基本用法,用free命令查看内存空余信息是Linux系统入门学习中的基础知识,需要的朋友可以参考下 free 命令显示系统使用和空闲的内存情况,包括 ...
- python判断一个数是不是完全平方数
思路: 完全平方数开根号后是一个整数,非完全平方数开根号的话是一个非整数 开根号后取整,如果开根号后是整数的话就不会改变值的大小 取整后再平方,如果值和之前一样,说明是完全平方数 import mat ...
- Oracle表的Rowid字段
Rowid 字段类型: Rowid 是一行数据的一个唯一标识. ROWID 是数据的详细地址,通过 rowid,oracle 可以快速的定位某行具体的数据的位置. ROWID 可以分为物理 rowid ...
- Brain的同步规则
这段话来自Java编程思想并发一章 什么时候使用同步 如果你正在写一个变量,它可能接下来将被另一个线程读取,或者正在读取一个上一次已经被另一个线程写过的变量,那么你必须使用同步,并且,读写线程都必须用 ...
- Java常见数据结构
HashMap深入浅出 HashMap数据结构 HashMap的本质就是一个数组加链表,数组默认长度是16,存储的元素达到总长度的75%就会扩容一倍.map.put(key,val),实际上就是根据h ...
- div+css布局教程(1)
margin:Margin属性用于设置两个元素之间的距离. 后面如果只有两个参数的话,第一个表示top和bottom,第二个表示left和right因为0 auto,表示上下边界为0,左右则根据宽度自 ...
- SpringMVC整体架构
总结: 1. 用户发起请求到前端控制器(DispatchServlet): 2. 前端控制器没有处理业务逻辑的能力,需要找到具体的模型对象处理(Handler),到处理器映射器中查找Handler对象 ...
- SpringDataJpa实体类常用注解
最近公司在使用SpringDataJpa时,需要创建实体类,通过实体类来创建数据库表结构,生成数据库表. 下面我们就来看下在创建实体类时一些常用的注解吧!!! 1.实体类常用注解 @Entity 标识 ...
- 转载:mysql数据库连接自动断开
转自:https://www.cnblogs.com/ay-a/p/10520425.html MySql连接空闲8小时自动断开引起的问题 一.问题描述 最近遇到了一个奇怪的MySql数据库问 ...
- 自己实现一个简化版的SpringMVC框架
废话不多说,我们进入今天的正题,在Web应用程序设计中,MVC模式已经被广泛使用.SpringMVC以DispatcherServlet为核心,负责协调和组织不同组件以完成请求处理并返回响应的工作,实 ...