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

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. amaze ui 滚动监听

    引入   此框架的css  js    前提还要有jquery http://amazeui.org/javascript/scrollspy 然后看这个链接里的各种动画 运用方法就是  在你想要有动 ...

  2. 面试知识点准备-C++常见问题

    博客园写写格式简单的文章还行,格式一复杂就不行了,可能是我不会用吧,我有强迫症,有道云格式很好用,以后去有道写这种东西了 有道云笔记链接:http://note.youdao.com/noteshar ...

  3. 3--Postman--变量(environment&global)

    (1) Environment clear an environment variable: pm.environment.unset("variable_key")--recom ...

  4. redis命令Set类型(七)

    集合类型 集合类型:无序.不可重复 列表类型:有序.可重复 命令: 1>增加/删除元素 语法:SADD key member [member -] 127.0.0.1:6379> sadd ...

  5. 第一模块 Python开发入门

    第一章 Python语法基础 变量的定义规范 一.声明变量 name = "Alex" 二.变量的定义规则 变量名只能是字母.数字或下划线的任意组合 变量名的第一个字符不能是数字 ...

  6. bug狩猎

    最近需求少了,终于有时间修一下底层的bug,做一点工具方便查bug,写篇文章简单记录一下. 一是优化了一个玩法进程的启动速度.这个玩法需要用战力做匹配,玩家按战力分段放进不同的桶里,每个桶用skipl ...

  7. git和redmine同步

    最近实现了github以及内部的gitbucket与redmine的同步. redmine是内部使用的一套工单系统,用于跟踪bug和需求,由于最近同时开发的版本比较多,在不同分支的提交容易漏掉.现在改 ...

  8. FileUrl

    package com.rscode.credits.util; import java.io.BufferedReader; import java.io.File; import java.io. ...

  9. 部署springboot工程到linux上及遇到的坑

    一.步骤 1.将工程打成jar包 IDEA中点击file-project structure,如下图: 选择Artifacts-JAR-From modules,选择入口类Main Class,如下图 ...

  10. 12集合(3)-----Map

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