Spring AOP使用注解记录用户操作日志
最后一个方法:核心的日志记录方法
package com.migu.cm.aspect;
import com.alibaba.fastjson.JSON;
import com.migu.cm.domain.UserOperationLog;
import com.migu.cm.service.UserOperationLogService;
import com.migu.cm.utils.Slf4jLogUtil;
import com.migu.cm.utils.ThreadLocalUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
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.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Aspect
@Order(1)
@Component
public class WebLogAspect {
/**
* 站位符:requestUrl>methodType>DeclaringTypeName.SignatureName>requestParams
*/
private final static String BEFORE_MATCH_STANCE_LOG = "{} {} {} {}";
/**
* 站位符:requestUrl>methodType>DeclaringTypeName.SignatureName>requestParams>responseInfo>cost
*/
private final static String AFTER_MATCH_STANCE_LOG = "{} {} {} {} {} {}";
@Autowired
private UserOperationLogService userOperationLogService;
@Pointcut("execution(public * com.migu.cm.web..*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
ThreadLocalUtil.set("startTime", System.currentTimeMillis());
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
ThreadLocalUtil.set("loggerTag", request.getHeader("loggerTag") == null ? UUID.randomUUID().toString() : request.getHeader("loggerTag"));
StringBuffer requestUrl = new StringBuffer(request.getRequestURL());
String requestParam = getRequestParam(joinPoint, request);
recordHandlers();
if (!StringUtils.isEmpty(request.getQueryString())) {
requestUrl.append("?").append(URLDecoder.decode(request.getQueryString(), "utf-8"));
}
Slf4jLogUtil.SimpleLogUtil.infoToController(BEFORE_MATCH_STANCE_LOG, requestUrl.toString()
, request.getMethod(), joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()
, requestParam);
// 用户操作记录(对数据增,删,改)
logInterception(request);
}
/**
* 记录每次请求的操作者记录
*/
private void recordHandlers() {
//打印请求用户名
try {
if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserDetails) {
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (userDetails != null) {
StringBuilder strBuilder = new StringBuilder();
strBuilder.append("username:").append(userDetails.getUsername());
Slf4jLogUtil.SimpleLogUtil.info(strBuilder.toString());
}
}
} catch (Exception e) {
Slf4jLogUtil.SimpleLogUtil.error("doBefore error", e);
}
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
// 处理完请求,返回内容
Object[] object = joinPoint.getArgs();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
StringBuffer requestUrl = new StringBuffer(request.getRequestURL());
if (!StringUtils.isEmpty(request.getQueryString())) {
requestUrl.append("?").append(URLDecoder.decode(request.getQueryString(), "utf-8"));
}
String requestParam = getRequestParam(joinPoint, request);
String responseParam = getResponseParam(ret);
Slf4jLogUtil.SimpleLogUtil.infoToController(AFTER_MATCH_STANCE_LOG, requestUrl.toString()
, request.getMethod(), joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()
, requestParam, responseParam
, (System.currentTimeMillis() - (long) ThreadLocalUtil.get("startTime")));
ThreadLocalUtil.remove();
}
/**
* 根据请求方式获取requestParam
*
* @param joinPoint
* @param request
* @return
*/
private String getRequestParam(JoinPoint joinPoint, HttpServletRequest request) {
String params = "[]";
if (request.getContentType() != null) {
switch (request.getContentType()) {
case "application/x-www-form-urlencoded":
params = StringUtils.isEmpty(request.getParameterMap()) ? "[]" : JSON.toJSONString(request.getParameterMap());
break;
case "application/json":
params = JSON.toJSONString(joinPoint.getArgs());
break;
case "application/x-www-form-urlencoded; charset=UTF-8":
params = StringUtils.isEmpty(request.getParameterMap()) ? "[]" : JSON.toJSONString(request.getParameterMap());
break;
default:
params = "[]";
break;
}
}
return params;
}
/**
* 根据实际业务处理输出的responseParam
*
* @param ret
* @return
*/
private String getResponseParam(Object ret) {
if (ret instanceof String) {
Map returnUrl = new HashMap(16);
returnUrl.put("returnAddress", ret);
return JSON.toJSONString(returnUrl);
}
return JSON.toJSONString(ret);
}
private final String UNKNOWN = "unknown";
/***
* 用户操作记录,(对数据库增,删,改)
* @param request
*/
public void logInterception(HttpServletRequest request ) {
try {
// TODO 这里处理下, 如果没有2个 / / 就不要拦截了, 造成的index 越界不好
String requestURI = request.getRequestURI();
String path = requestURI.substring(1);
int index = path.indexOf("/");
String sub2 = path.substring(index+1);
int index2 = sub2.indexOf("/");
String sub3 = sub2.substring(0, index2);
if (sub3.indexOf("add") >= 0 || sub3.indexOf("update") >= 0 || sub3.indexOf("cancel") >= 0 || sub3.indexOf("del") >= 0 || sub3.indexOf("toTop") >= 0
|| sub3.indexOf("make") >= 0 || sub3.indexOf("effect") >= 0 || sub3.indexOf("save") >= 0 || sub3.indexOf("insert") >= 0
|| sub3.indexOf("login") >= 0 || sub3.indexOf("edit") >= 0 || sub3.indexOf("approve") >= 0 || sub3.indexOf("modify") >= 0
|| sub3.indexOf("active") >= 0 || sub3.indexOf("doPackage") >= 0 || sub3.indexOf("doDownload") >= 0 || sub3.indexOf("close") >= 0
|| sub3.indexOf("remove") >= 0) {
UserOperationLog userOperationLog = new UserOperationLog();
//日志记录
try {
if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserDetails) {
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (userDetails != null) {
StringBuilder strBuilder = new StringBuilder();
strBuilder.append("username:").append(userDetails.getUsername());
userOperationLog.setUsername(userDetails.getUsername());
Slf4jLogUtil.SimpleLogUtil.info(strBuilder.toString());
}
}
} catch (Exception e) {
Slf4jLogUtil.SimpleLogUtil.error("doBefore error", e);
}
userOperationLog.setPath(requestURI);
//时间
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
userOperationLog.setIp(ip);
userOperationLog.setCreatetime(new Date());
int paramsIndex = request.getQueryString().lastIndexOf("=");
String params = request.getQueryString().substring(0,paramsIndex-2);
userOperationLog.setParams(params);
userOperationLogService.saveInfo(userOperationLog);
}
} catch (Exception e) {
Slf4jLogUtil.SimpleLogUtil.error("用户操作记录获取异常:", e);
}
}
}
Spring AOP使用注解记录用户操作日志的更多相关文章
- RabbitMQ实战场景(一):异步记录用户操作日志
传统的项目开发中业务流程以串行方式,执行了模块1—>模块2–>模块3 而我们知道,这个执行流程其实对于整个程序来讲是有一定的弊端的,主要有几点: (1)整个流程的执行响应等待时间比较长; ...
- ssm 项目记录用户操作日志和异常日志
借助网上参考的内容,写出自己记录操作日志的心得!! 我用的是ssm项目使用aop记录日志:这里用到了aop的切点 和 自定义注解方式: 1.建好数据表: 数据库记录的字段有: 日志id .操作人.操作 ...
- springAOP记录用户操作日志
项目已经开发完成,需要加用户操作日志,如果返回去加也不太现实,所以使用springAOP来完成比较合适. 注解工具类: @Retention(RetentionPolicy.RUNTIME) @Tar ...
- linux 记录用户操作日志
将以下加入到/etc/profile 最后 history USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]/ ...
- 我使用Spring AOP实现了用户操作日志功能
我使用Spring AOP实现了用户操作日志功能 今天答辩完了,复盘了一下系统,发现还是有一些东西值得拿出来和大家分享一下. 需求分析 系统需要对用户的操作进行记录,方便未来溯源 首先想到的就是在每个 ...
- 微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录
在前面的Part3中, 我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立 ...
- spring AOP自定义注解方式实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- spring AOP自定义注解 实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
随机推荐
- 鼠标跟随效果 vue或者js通用
this.$refs.tooltip.getBoundingClientRect() => 用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. ...
- MongoDB的安装和使用
Step1:下载和安装 下载地址:http://dl.mongodb.org/dl/win32/x86_64 安装:一直按照默认指示去安装或者选择自己喜欢的路径安装. Step2:配置环境变量 安装完 ...
- RabbitMQ和kafka从几个角度简单的对比
业界对于消息的传递有多种方案和产品, 本文就比较有代表性的两个MQ(rabbitMQ,kafka)进行阐述和做简单的对比 在应用场景方面,RabbitMQ,遵循AMQP协议,由内在高并发的erlann ...
- 面向对象的JavaScript-小结
Javascript中的类 类是对象的模板,用于创建共享一系列属性和方法的类似对象. 使用new关键字调用函数,可以创建对象实例. function Accommodation(){}; var ho ...
- 利用 SPICE 分析理解心电图前端中的右腿驱动
[导读] 心电图(ECG)学是一门将心脏离子去极(ionic depolarization) 后转换为分析用可测量电信号的科学.模拟电子接口到电极/患者设计中最为常见的难题之一便是优化右腿驱动 ( ...
- python学习4---实现快速排序
1.QuickSort def Rand_Partition(A,p,r): """ 划分数组的元素下标q :param A: 数组 :param p: 数组左边界 :p ...
- POJ1064 Cable master(二分 浮点误差)
题目链接:传送门 题目大意: 给出n根长度为1-1e5的电线,想要从中切割出k段等长的部分(不可拼接),问这个k段等长的电线最长可以是多长(保留两位小数向下取整). 思路: 很裸的题意,二分答案即可. ...
- 在进行多次scanf时,printf输出错误
随便一处代码,经过改正后,输出正确的 ''' #include <stdio.h> int main(){ int T; scanf("%d",&T ...
- 关于使用jQuery操作dom时的一点发现
<body> <ul> <li>list item 1</li> <li>list item 2</li> <li> ...
- node连接mongodb(简略版)
1.先通过配置启动mongodb,然后新建db.js 已经对相对应的数据库操作增删改查封装完成. //这个模块里面封装了所有对数据库的常用操作 var MongoClient = requir ...