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. C++中map和unordered_map的用法

    1. 简介 map和unordered_map都是c++中可以充当字典(key-value)来用的数据类型,但是其基本实现是不一样的. 2. map 对于map的底层原理,是通过红黑树(一种非严格意义 ...

  2. teach-es6

    ES6: ECMAScript6 js: 组成部分: ECMA DOM BOM ECMA是“European Computer Manufactures Association”的缩写,中文称欧洲计算 ...

  3. sqlalchemy orm 层面删除数据注意

    #encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Text ...

  4. python 爬虫 requests模块 目录

    requests模块(response常用属性) 基于requests模块的get请求 基于requests模块发起ajax的get请求 基于requests模块发起ajax的post请求

  5. Elasticsearch-数值类型

    Elasticsearch-数值类型 数值类型可以是浮点数,也可以是费浮点数.如果不需要小数,可以选择byte.short.int或者long.如果确实需要小数,可以选择float和double.这些 ...

  6. IIS 404设置

    想给自己做的的网站自定义一个404页面,开始 双击红框提示的错误页图标 双击上图红框提示的所示404行 修改上图红框提示的内容如下:我是直接在根目录放了一个自己做的404.html,实际情况要填写你自 ...

  7. ZooKeeper的ACL权限

    ACL控制权限 什么是ACL(Access Control List访问控制列表) 针对节点可以设置相关读写等权限, 目的为了保障数据安全性 权限permission可以指定不同的权限范围以及角色 A ...

  8. Manacher模版

    现在讲的也是一种处理字符串的方法,叫做Manacher,有点像“马拉车” 1179: [视频][Manacher]最长回文子串 时间限制: 1 Sec  内存限制: 128 MB提交: 209  解决 ...

  9. TCP三次握手与四次挥手详解(最全面)

    目录 TCP的三次握手与四次挥手 TCP报文段的首部格式 TCP的工作原理 TCP 的流量控制 TCP的拥塞控制 拥塞控制与流量控制的关系 拥塞控制所起的作用 慢开始和拥塞避免 慢开始算法的原理 三次 ...

  10. 剑指Offer 1-41 代码(python实现)

    今天主要写了一下offer 1-41题,余下的稍后整理 1 """ 1 镜像二叉树: 递归 """ def mirror(root): if ...