spring Aspect 实现自定义注解的日志记录

由于直接拦截所有的controller所以需要spring.xml中添加
<aop:aspectj-autoproxy proxy-target-class="true" />  交由cglib代理。

使用只要在controller的method上加上
@ActionControllerLog(channel="web",action="user_register",title="用户注册",isSaveRequestData=true)
其中isSavveRequestData代表是否保存请求参数,默认为false。

  1 import java.lang.reflect.Method;
  2 import java.util.Date;
  3 import java.util.Map;
  4
  5 import javax.annotation.Resource;
  6 import javax.servlet.http.HttpServletRequest;
  7
  8 import org.aspectj.lang.JoinPoint;
  9 import org.aspectj.lang.Signature;
 10 import org.aspectj.lang.annotation.AfterReturning;
 11 import org.aspectj.lang.annotation.AfterThrowing;
 12 import org.aspectj.lang.annotation.Aspect;
 13 import org.aspectj.lang.annotation.Pointcut;
 14 import org.aspectj.lang.reflect.MethodSignature;
 15 import org.slf4j.Logger;
 16 import org.slf4j.LoggerFactory;
 17 import org.springframework.stereotype.Component;
 18 import org.springframework.web.context.request.RequestContextHolder;
 19 import org.springframework.web.context.request.ServletRequestAttributes;
 20
 21 import com.alibaba.fastjson.JSONObject;
 22 import com.dlodlo.model.BusUserModel;
 23 import com.dlodlo.model.BusUserlogModel;
 24 import com.dlodlo.service.BusUserlogService;
 25
 26 @Aspect
 27 @Component
 28 public  class SystemLogAspect {
 29     //注入Service用于把日志保存数据库
 30     @Resource
 31     private BusUserlogService busUserlogService;
 32     //本地异常日志记录对象
 33     private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);
 34
 35     //Controller层切点
 36     @Pointcut("@annotation(com.dlodlo.util.ActionControllerLog)")
 37     public  void controllerAspect() {
 38     }
 39
 40     /**
 41      * 前置通知 用于拦截Controller层记录用户的操作
 42      *
 43      * @param joinPoint 切点
 44      */
 45     @AfterReturning(pointcut="controllerAspect()")
 46     public  void doBefore(JoinPoint joinPoint) {
 47         handleLog(joinPoint,null);
 48     }
 49
 50
 51 //    @AfterReturning(pointcut="controllerAspect()",argNames = "joinPoint,retVal",returning = "retVal")
 52     @AfterThrowing(value="controllerAspect()",throwing="e")
 53     public void doAfter(JoinPoint joinPoint,Exception e)
 54     {
 55         handleLog(joinPoint,e);
 56     }
 57
 58 private void handleLog(JoinPoint joinPoint,Exception e) {
 59     try {
 60         //获得注解
 61         ActionControllerLog controllerLog = giveController(joinPoint);
 62         if(controllerLog == null)
 63         {
 64             return;
 65         }
 66         //获取当前的用户
 67         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
 68         BusUserModel userModel = (BusUserModel) SessionUtil.getAttrAsObject(request, SessionUtil.SESSION_USER);
 69
 70         //*========数据库日志=========*//
 71         BusUserlogModel userlogModel = new BusUserlogModel();
 72         //请求的IP
 73         String ip = MethodUtil.getIpAddr(request);
 74         userlogModel.setUserIp(ip);
 75         userlogModel.setCreateTIme(new Date());
 76         userlogModel.setUrl(request.getRequestURI());
 77         if(userModel != null)
 78         {
 79             userlogModel.setUserId(userModel.getId().longValue());
 80             userlogModel.setUserName(userModel.getUserName());
 81         }
 82
 83         if(e != null)
 84             userlogModel.setErrorMessage(e.getMessage());
 85
 86         //处理设置注解上的参数
 87         getControllerMethodDescription(controllerLog,userlogModel,request);
 88         //保存数据库
 89         busUserlogService.insert(userlogModel);
 90       }  catch (Exception exp) {
 91        //记录本地异常日志
 92        logger.error("==前置通知异常==");
 93        logger.error("异常信息:{}", exp.getMessage());
 94        exp.printStackTrace();
 95       }
 96 }
 97
 98     /**
 99      * 获取注解中对方法的描述信息 用于Controller层注解
100      *
101      * @param joinPoint 切点
102      * @return 方法描述
103      * @throws Exception
104      */
105      public  static void getControllerMethodDescription(ActionControllerLog controllerLog,BusUserlogModel userlogModel,HttpServletRequest request)  throws Exception {
106         //设置action动作
107         userlogModel.setAction(controllerLog.action());
108         //设置标题
109         userlogModel.setTitle(controllerLog.title());
110         //设置channel
111         userlogModel.setChannel(controllerLog.channel());
112         //是否需要保存request,参数和值
113         if(controllerLog.isSaveRequestData())
114         {
115             //获取参数的信息,传入到数据库中。
116             setRequestValue(userlogModel,request);
117         }
118      }
119
120      /**
121       * 获取请求的参数,放到log中
122       * @param userlogModel
123       * @param request
124       */
125     @SuppressWarnings("rawtypes")
126     private static void setRequestValue(BusUserlogModel userlogModel,HttpServletRequest request) {
127         if(userlogModel == null)
128             userlogModel = new BusUserlogModel();
129         Map map = request.getParameterMap();
130         String params = JSONObject.toJSONString(map);
131         userlogModel.setRequestParam(params);
132     }
133
134     /**
135      * 是否存在注解,如果存在就记录日志
136      * @param joinPoint
137      * @param controllerLog
138      * @return
139      * @throws Exception
140      */
141     private static ActionControllerLog giveController(JoinPoint joinPoint) throws Exception
142     {
143         Signature signature = joinPoint.getSignature();
144         MethodSignature methodSignature = (MethodSignature) signature;
145         Method method = methodSignature.getMethod();
146
147         if(method != null)
148         {
149             return method.getAnnotation(ActionControllerLog.class);
150         }
151         return null;
152     }
153 }

注解类

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ActionControllerLog {
    /** 标题 */
    String title()  default "";
    /** 动作的名称 */
    String action() default "";
    /** 是否保存请求的参数 */
    boolean isSaveRequestData() default false;
    /** 渠道 */
    String channel() default "web";
}
时间: 2024-10-29 17:31:54

spring Aspect 实现自定义注解的日志记录的相关文章

(转)利用Spring AOP自定义注解解决日志和签名校验

一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: boolean isValid = accountService.validSignature(appid, signature, client_signature); if (!isValid) return ErrorUtil.buildError(ErrorUtil.ERR_CODE_COM

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

转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: boolean isValid = accountService.validSignature(appid, signature, client_signature); if (!

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

今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在applicationContext-mvc.xml中要添加的 <mvc:annotation-driven />     <!-- 激活组件扫描功能,在包com.gcx及其子包下面自动扫描通过注解配置的组件 -->     <context:component-scan base-pac

spring统一日志管理,切面(@Aspect),注解式日志管理

step1 开启切面编程 <!-- 开启切面编程(通过配置织入@Aspectj切面 ) --> <aop:aspectj-autoproxy/> <aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强.

java动态代理详解,并用动态代理和注解实现日志记录功能

动态代理的概念 动态代理是程序在运行过程中自动创建一个代理对象来代替被代理的对象去执行相应的操作,例如, 我们有一个已经投入运行的项目中有一个用户DAO类UserDao用来对User对象进行数据库的增删改查操作,但是有一天,要求在对用户的增删改查操作时记录相应的日志,这是怎么办呢?难道我们去直接修改UserDao的源代码,然后在UserDao的每个方法中加入日志记录功能,这显然是不合理的,它违背了java的OCP原则,即对修改关闭对扩张开放.比如改现有的代码如下: 接口类 public inte

spring框架校验自定义注解

起因: 项目开发时遇到一个问题是对于金额类型的字段,数据库中格式一般为BigDecimal类型,两位小数点,然后在接口定义中如果不定义成String类型的话,就不能使用@pattern注解限定格式,而在hibernate的校验里面,没有相关适合的注解使用来限定金额格式,所以需要自定义一个注解来对这类参数进行校验.如果在接口中传入的参数值小数点后不止两位,在mysql中进行插入的时候会自动进行剪切,如传入1.315元,在入库的时候该参数就可能被剪切成1.35元,最终入库数据为1.35. 解决:自定

操作日志记录

1.存在的意义 所日志记录,就是记录所有的操作,使领导对这个系统的流转了如指掌,同时要是系统出现了问题,也可以清楚找到问题的所在. 2. 界面展示 3. 主要代码分析(提供三种方法)   3.1 方法一 使用aop实现 源码介绍: 01.首先在保证你的环境无误的情况下(我用的是ssh) 02.BussAnnotation.java  (自定义注解) package cn.bdqn.annotation; /** * 自定义注解(用于记录日志) */ import java.lang.annota

自定义错误日志记录类

引言 这是一个简单的自定义的错误日志记录类,这里我主要用于API接口开发中,APP移动端的入参记录 日志参数 /// <summary> /// 日志参数 /// </summary> public static class LogReq { /// <summary> /// 入参 /// </summary> public static string LogReqStr = ""; /// <summary> /// 加密

springBoot AOP环绕增强、自定义注解、log4j2、MDC

(一)log4j2 maven配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!-- 切换log4j2日志读取 --> <exclusion> <groupId>org.springframework.b