通过AOP自定义注解实现记录用户操作日志。

前言:

通过自定义注解和AOP结合的方式,实现日志的记录功能

大致流程:项目运行->用户操作调用业务处理类->通过自定义的注解(我理解为一个切点)->进入到AOP切面类(在这里可以获得业务处理类的类名,方法名,通过request获取操作者ip,自定义的操作名,时间等)->把获取的信息记入数据库实现日志的记录->记录成功后返回业务处理类,下面是代码。

1.spring-mvc配置文件

    <!-- 6.开启注解AOP (前提是引入aop命名空间和相关jar包) -->
    <aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true"></aop:aspectj-autoproxy>

    <!-- 7.开启aop,对类代理强制使用cglib代理 -->
    <aop:config proxy-target-class="true"></aop:config>

    <!-- 8.扫描 @Service @Component 注解-->
    <context:component-scan base-package="com.bs" >
        <!-- 不扫描 @Controller的类 -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

  

2.自定义注解类

package com.bs.annotation;

import java.lang.annotation.*;


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SysLog {

	String value() default "";
}

  

3.AOP切面类

package com.bs.aop;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.Date;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.bs.annotation.SysLog;
import com.bs.basic.service.BsSysLogService;

@Aspect
@Component
public class LogAspect {

	
    private static final String LOG_CONTENT = "[类名]:%s <br/>[方法]:%s <br>[参数]:%s <br/>[IP]:%s";
    
    @Autowired
    public BsSysLogService logService;
    
    @Around("@annotation(com.bs.annotation.SysLog)")
    public Object saveLog(ProceedingJoinPoint joinPoint) throws Throwable{
		
		DateFormat ddtf = DateFormat.getDateTimeInstance();
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		Object result = null;
		String methodName = joinPoint.getSignature().getName();
        Method method = currentMethod(joinPoint, methodName);
        SysLog log = method.getAnnotation(SysLog.class);
        String content =buildeContent(joinPoint, methodName, request);
        
        logService.insert(content,ddtf.format(new Date()),"-",log.value());
        try{
        	result=joinPoint.proceed();
        }catch(Exception exception){
        	
        }finally{
        }
        return result;
	}
	
	 /**
     * 获取当前方法
     * @param joinPoint
     * @param methodName
     * @return
     */
    public  Method currentMethod(ProceedingJoinPoint joinPoint,String methodName){
        Method[] methods = joinPoint.getTarget().getClass().getMethods();
        Method resultMethod = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                resultMethod = method;
                break;
            }
        }
        return resultMethod;
    }
    
    /**
     * 日志内容
     * @param joinPoint
     * @param methodName
     * @param request
     * @return
     */
    public String buildeContent(ProceedingJoinPoint joinPoint, String methodName, HttpServletRequest request) {
        String className = joinPoint.getTarget().getClass().getName();
        Object[] params = joinPoint.getArgs();
        StringBuffer bf = new StringBuffer();
        if (params != null && params.length > 0) {
            Enumeration<String> paraNames = request.getParameterNames();
            while (paraNames.hasMoreElements()) {
                String key = paraNames.nextElement();
                bf.append(key).append("=");
                bf.append(request.getParameter(key)).append("&");
            }
            if (StringUtils.isBlank(bf.toString())) {
                bf.append(request.getQueryString());
            }
        }
        return String.format(LOG_CONTENT, className, methodName, bf.toString(),getRemoteAddress(request));
    }
    
    
    /**
    *
    * 获取请求客户端ip
    *
    * @param request
    *
    * @return ip地址
    *
    */
   public static  String getRemoteAddress(HttpServletRequest request) {

       String ip = request.getHeader("x-forwarded-for");
       if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
           ip = request.getHeader("Proxy-Client-IP");
       }
       if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
           ip = request.getHeader("WL-Proxy-Client-IP");
       }
       if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
           ip = request.getRemoteAddr();
       }
       return ip;
   }
}

4.自定义注解配置在需要记录的业务处理类

@SysLog("删除场景")
	@Override
	public String deleteScene(String cmdValues) {
		//业务逻辑....
	}
@SysLog("更新场景")
	@Override
	public String updateScene(String value) {
        //业务处理...
}

...

记录的日志是这样的

posted @ 2019-03-29 17:58  人生何处不青山丶z  阅读(602)  评论(0编辑  收藏  举报