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 实现日志的更多相关文章

  1. Spring AOP 完成日志记录

    Spring AOP 完成日志记录 http://hotstrong.iteye.com/blog/1330046

  2. Spring AOP进行日志记录

    在java开发中日志的管理有很多种.我一般会使用过滤器,或者是Spring的拦截器进行日志的处理.如果是用过滤器比较简单,只要对所有的.do提交进行拦截,然后获取action的提交路径就可以获取对每个 ...

  3. [置顶] 使用sping AOP 操作日志管理

    记录后台操作人员的登陆.退出.进入了哪个界面.增加.删除.修改等操作 在数据库中建立一张SYSLOG表,使用Sping 的AOP实现日志管理,在Sping.xml中配置 <!-- Spring ...

  4. Spring AOP进行日志记录,管理

    在java开发中日志的管理有很多种.我一般会使用过滤器,或者是Spring的拦截器进行日志的处理.如果是用过滤器比较简单,只要对所有的.do提交进行拦截,然后获取action的提交路径就可以获取对每个 ...

  5. Spring Boot 入门(五):集成 AOP 进行日志管理

    本篇文章是接着 Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了 Pagehelper+MyBatis 分页 ...

  6. spring aop实现日志收集

    概述 使用spring aop 来实现日志的统一收集功能 详细 代码下载:http://www.demodashi.com/demo/10185.html 使用spring aop 来实现日志的统一收 ...

  7. 自定义注解-aop实现日志记录

    关于注解,平时接触的可不少,像是 @Controller.@Service.@Autowried 等等,不知道你是否有过这种疑惑,使用 @Service 注解的类成为我们的业务类,使用 @Contro ...

  8. 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 ...

  9. 【Java分享客栈】超简洁SpringBoot使用AOP统一日志管理-纯干货干到便秘

    前言 请问今天您便秘了吗?程序员坐久了真的会便秘哦,如果偶然点进了这篇小干货,就麻烦您喝杯水然后去趟厕所一边用左手托起对准嘘嘘,一边用右手滑动手机看完本篇吧. 实现 本篇AOP统一日志管理写法来源于国 ...

  10. 【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】

    一.需求分析 日志数据在很多行业中都是非常敏感的数据,它们不能删除只能保存和查看,这样日志表就会越来越大,我们不可能永远让它无限制的增长下去,必须采取一种手段将数据分散开来.假设现在整个数据库需要保存 ...

随机推荐

  1. AKKA文档2.2(java)——术语,概念

    原文:http://doc.akka.io/docs/akka/2.3.6/general/terminology.html 译者:吴京润 本章我们试图建立一个通用的术语列表,用来定义有关并发和分布式 ...

  2. [c++] 链表各类操作详解

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...

  3. 自然语言处理工具pyhanlp分词与词性标注

    Pyhanlp分词与词性标注的相关内容记得此前是有分享过的.可能时间太久记不太清楚了.以下文章是分享自“baiziyu”所写(小部分内容有修改),供大家学习参考之用. 简介 pyhanlp是HanLP ...

  4. 虚拟机上安装Linux系统之ubuntu

    以前自己在虚拟机上安装过几回Linux系统,有centos.ubuntu,不过都没来得及写一个安装教程,今天正好需要重新安装一下,就分享一个安装ubuntu的详细教程 安装前准备: VMWare虚拟机 ...

  5. 升级降级(期望DP)2019 Multi-University Training Contest 7 hdu杭电多校第7场(Kejin Player)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意: 有 1~n 个等级,你现在是1级,求升到n级的花费期望.会给你n个条件(i~i+1级升级 ...

  6. python基础之函数进阶

    假如有一个函数,实现返回两个数中的较大值: def my_max(x,y): m = x if x>y else y return mbigger = my_max(10,20)print(bi ...

  7. 如何同步多个 git 远程仓库

    请看 -> 如何同步多个 git 远程仓库

  8. nginx+php设置大文件请求上传(502及504问题处理)

    502问题 php-fpm 修改项: request_terminate_timeout 位置: eg: /etc/php5/fpm2/pool.d/www.conf ; The timeout fo ...

  9. springBoot 打包上线跳过连接数据库

    在pom文件下添加 <skipTests>true</skipTests> 这一行 如下: <properties> <project.build.sourc ...

  10. python中同步、多线程、异步IO、多线程对IO密集型的影响

    目录 1.常见并发类型 2.同步版本 3.多线程 4.异步IO 5.多进程 6.总结 1.常见并发类型 I/ O密集型: 蓝色框表示程序执行工作的时间,红色框表示等待I/O操作完成的时间.此图没有按比 ...