最后一个方法:核心的日志记录方法

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使用注解记录用户操作日志的更多相关文章

  1. RabbitMQ实战场景(一):异步记录用户操作日志

    传统的项目开发中业务流程以串行方式,执行了模块1—>模块2–>模块3 而我们知道,这个执行流程其实对于整个程序来讲是有一定的弊端的,主要有几点: (1)整个流程的执行响应等待时间比较长; ...

  2. ssm 项目记录用户操作日志和异常日志

    借助网上参考的内容,写出自己记录操作日志的心得!! 我用的是ssm项目使用aop记录日志:这里用到了aop的切点 和 自定义注解方式: 1.建好数据表: 数据库记录的字段有: 日志id .操作人.操作 ...

  3. springAOP记录用户操作日志

    项目已经开发完成,需要加用户操作日志,如果返回去加也不太现实,所以使用springAOP来完成比较合适. 注解工具类: @Retention(RetentionPolicy.RUNTIME) @Tar ...

  4. linux 记录用户操作日志

    将以下加入到/etc/profile 最后 history USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]/ ...

  5. 我使用Spring AOP实现了用户操作日志功能

    我使用Spring AOP实现了用户操作日志功能 今天答辩完了,复盘了一下系统,发现还是有一些东西值得拿出来和大家分享一下. 需求分析 系统需要对用户的操作进行记录,方便未来溯源 首先想到的就是在每个 ...

  6. 微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录

    在前面的Part3中, 我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立 ...

  7. spring AOP自定义注解方式实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  8. spring AOP自定义注解 实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  9. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

随机推荐

  1. loadrunner的安装与破解

    https://pan.baidu.com/s/1H4Cj0ySTwqPra5OA3nicmw 背景: 由于想做服务器的性能测试,所以最近有意研究一下loadrunner这个工具,下面仅将安装过程做个 ...

  2. 自动化测试-17.selenium数据的分离之txt文本的写入与读取

    前言 数据量偏小时,用txt文本保存数据比较合适,以-进行区分,为什么不用:呢?原因是,我们在使用数据时,会存在url地址的情况,里面宝行:所以用-进行替代 此处附上代码 #encoding=utf- ...

  3. vue--http请求的封装--token

    export const FetchHandler = function (url,opt) { let paramStr = ''; let token = ''; for(key in opt){ ...

  4. phoneshop cs6破解

    一.以“试用”方式安装photoshop: 二.下载amtlib.dll破解文件,密码:ubx2: 三.备份photoshop目录下的amtlib.dll文件,将下载的amtlib.dll文件拷贝到p ...

  5. ubuntu mariadb installation

    sudo apt-get install mariadb-server[sudo] password for wadmin: Reading package lists... DoneBuilding ...

  6. ubuntu18.04LTS修改键盘键位

    在Linux中为了敲命令方便,所以需要做一下键盘键位调整: 1.Esc键和`(即数字键1前面的那个键)对换: 2.Caps Lock键和左Control键对换: 编辑键位文件: sudo vim /u ...

  7. Homestead的安装配置

    laravel学院教程 : http://laravelacademy.org/post/7658.html 参考博文:https://blog.csdn.net/xyxjn/article/deta ...

  8. 12集合(1)-----List

    一.总体分类 Collection(包括方法add,remove,contains,clear,size) List(接口) LinkedList ArrayList Vector---Stack 2 ...

  9. idea搭建spring的demo

    这是本人在回顾知识点时记录的内容,如有错误,谢谢指正! 1.先来介绍下spring是什么? spring是一个轻量级的开源框架,是一个大型的容器,也是一个很好的“管家”,可以接管web层,业务层,da ...

  10. Visible Lattice Points SPOJ - VLATTICE 三维+莫比乌斯反演

    #include<bits/stdc++.h> #define ll long long using namespace std; ; int vis[maxn]; int mu[maxn ...