业务场景:pc端,登陆页面,登陆账户后,访问各个模块,每次访问和操作都记录日志.
1.开启aop,就一步.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
application.yml中下面这个设置默认开启
spring.aop.auto=true
2.增加一个自定义annotation
package com.yunchuang.config.annotation;
import java.lang.annotation.*;
/**
* 日志
*
* @author 尹冬飞
* @date 2015-07-02 15:43:26
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Log {
/**
* 1.日志内容
*/
String value();
}
3.定义切面类
package com.yunchuang.config.aspect;
import com.yunchuang.config.annotation.Log;
import com.yunchuang.console.user.domain.User;
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.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* aop切面日志
*
* @author 尹冬飞
* @create 2017-05-02 14:16
*/
@Aspect
@Component
public class LogAspect {
private Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Pointcut("execution(public * com.yunchuang.console.*.web..*.*(..))")
public void consoleLog() {
}
@Before("consoleLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//获取request
HttpServletRequest request = attributes.getRequest();
//获取session
HttpSession session = request.getSession();
//获取方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取方法
Method method = signature.getMethod(); //获取被拦截的方法
//获取自定义Log注解
Log annotation = method.getAnnotation(Log.class);
//如果有Log注解,则写入日志
if (annotation != null) {
//获取session里的用户对象
User user = (User) session.getAttribute("loginUser");
//获取用户名
String name = user != null ? "[" + user.getNickname() + "]" : "";
logger.info(name + "[" + annotation.value() + "][" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "][" + Arrays.toString(joinPoint.getArgs()) + "][" + request.getRemoteAddr() + "]");
}
}
@AfterReturning(returning = "ret", pointcut = "consoleLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
//logger.info("RESPONSE : " + ret);
}
}
这里关键的2个地方:
获取方法,就能获取自定义注解,就能获取里面的值
//获取方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
获取请求内容就能获取request和session
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
4.在controller的方法上增加自定义注解.
因为Log类里属性是value(),所以注解里不用写@Log(value="日志内容")
@Log("日志内容")
@GetMapping("/list")
public String list() {
return "console/user/list";
}
网友评论