controller日志AOP处理

1 定义注解

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

@Target({ElementType.PARAMETER, ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface WebLog {
    /**
     *  操作类型
     *  如:inbound
     */  
    public String operationType() default "";  

    /**
     * 操作名称
     * 如:入库
     * @return
     */
    public String operationName() default "";  
    /**
     * 业务类型
     * @return
     */
    public String businessType() default "";
}

2 AOP切面处理

import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.dzmsoft.framework.base.exception.OAuthException;
import com.dzmsoft.framework.base.util.CheckEmptyUtil;
import com.dzmsoft.framework.base.util.HttpUtil;
import com.dzmsoft.framework.log.dto.LogConstant;
import com.dzmsoft.framework.log.service.LogService;
import com.dzmsoft.framework.web.pojo.ShiroUser;
import com.dzmsoft.framework.web.util.UserUtil;
import com.google.gson.Gson;

/**
 * 页面级Controller切面
 * @author dzm
 *
 */
@Aspect
@Component
public class WebLogAspect {

    private static final Logger logger = LoggerFactory
            .getLogger(WebLogAspect.class);
    @Autowired
    private LogService logService;
    @Autowired
    private Gson gson;

    @Pointcut("@annotation(com.dzmsoft.framework.log.aop.WebLog)")
    public void controllerAspect() {

    }

    /**
     *  配置controller环绕通知,使用在方法aspect()上注册的切入点
     * @param joinPoint
     * @throws Throwable 
     */
    @Around("controllerAspect()")
    public Object around(ProceedingJoinPoint  joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = null;
        try {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            logger.info("执行类:{}, 方法:{}开始", targetName, methodName);
            result = joinPoint.proceed();
            long end = System.currentTimeMillis();
            if (logger.isInfoEnabled()) {
                logger.info("执行类:{}, 方法:{},总共耗时{}ms", targetName, methodName, (end - start) );
            }
            logger.info("执行类:{}, 方法:{}结束", targetName, methodName);
        } catch (Throwable e) {
            if (logger.isInfoEnabled()) {
                logger.error("异常结束,结束原因:{}", e.getMessage());
            }
            throw e;
        }
        return result;
    }

    /**
     * 后置通知 用于拦截Controller层记录用户的操作
     * @param joinPoint
     */
    @SuppressWarnings("rawtypes")
    @After("controllerAspect()")  
    public  void after(JoinPoint joinPoint){
        ShiroUser shiroUser = UserUtil.getCurrentShiroUser();
        if (shiroUser == null || CheckEmptyUtil.isEmpty(shiroUser.getId())){
            return ;
        }
        try{
            Object[] args = joinPoint.getArgs(); // 方法的参数
            HttpServletRequest request = getRequest(args);
            Map<String, String> params = HttpUtil.getRequestPara(request, false);
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Class targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getMethods();
            String operationType = "";
            String operationName = "";
            String bussinessType = "";
            String content = CheckEmptyUtil.isEmpty(params)?null:gson.toJson(params);
            for (Method method:methods){
                if (method.getModifiers()!=1 || !methodName.equals(method.getName())){
                    // 修饰符1表示public方法
                    continue;
                }
                operationType = method.getAnnotation(WebLog.class).operationType();
                operationName = method.getAnnotation(WebLog.class).operationName();
                bussinessType = method.getAnnotation(WebLog.class).businessType();
                // 添加日志进入hadoop中
                logService.addLog2Hadoop(shiroUser.getId(), shiroUser.getLoginName(), shiroUser.getName(),content,  operationType, operationName, LogConstant.WEB, bussinessType);
                // 找到匹配的即终止
                break;
            }
        } catch(Exception e){
            logger.error("==后置通知异常==");  
            logger.error("异常信息:{}", e.getMessage()); 
        }
    }

    private HttpServletRequest getRequest(Object[] args) throws OAuthException {
        // ServletRequestAttributes may be null, check it first.
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            return ((ServletRequestAttributes) requestAttributes).getRequest();
        }
        logger.debug("未找到HttpServletRequest参数");
        throw new IllegalArgumentException("未找到HttpServletRequest参数");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值