记录用户的信息,通过日志信息的分析可以分析用户的习惯
使用注解+Aop实现日志记录的原因:
aop 好处 新增代码逻辑不影响原有代码逻辑的执行
使用步骤
1.需要引入aop的jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.确定表结构
大致为: 操作 账号 密码 时间 用户ip地址 访问结果
3.创建一个自定义注解 用来加在方法上面,记录当前方法的操作代表什么
/**
* Created by lbypc on 2019/1/10.
* 注解在属性和方法上 标记当前方法的作用 用于日志记录
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceLog {
String value() default "";
}
例如:
@RequestMapping("adminLogin")
@ServiceLog("登录系统")
public String adminLogin(String username,String password){
boolean login = adminService.login(username, password);
if(login){
return "redirect:/main/main.jsp";
}
return "redirect:/login.jsp";
}
4.创建切面类
-
创建一个类 @Component @Aspect
-
创建切点 @Pointcut
-
创建增强 @Around
为什么要用环绕增强 :
因为需要获取用户在执行操作之前和之后的数据 -
看看需要什么参数
-
一个一个的获取
-
获取注解中的值
- 获取一个方法签名对象
- 获取方法对象
- 通过方法对象可以得到方法上的注解
- 得到注解中的值
-
获取ip
- 得到request
- 通过工具类和request得到ip
-
获取用户名和用户的id
- 获得session
- 获取用户对象
- 得到用户名和id
-
封装成对象
-
添加入数据库
package com.cmfz.cmfzback.aop;
import com.cmfz.cmfzback.annotaion.ServiceLog;
import com.cmfz.cmfzback.entity.AdminLog;
import com.cmfz.cmfzback.entity.CmfzAdmin;
import com.cmfz.cmfzback.service.AdminLogService;
import com.cmfz.cmfzback.util.IPKit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
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.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.Date;
@Aspect
@Component
public class LogAspect {
@Autowired
private AdminLogService adminLogService;
//创建类对象使用的是当前类
private final static Logger logger= LoggerFactory.getLogger(LogAspect.class);
/**
* 切到方法上
*/
@Pointcut("@annotation(com.cmfz.cmfzback.annotaion.ServiceLog)")
public void testLog(){}
@Around("testLog()")
public Object testLogAdd(ProceedingJoinPoint proceedingJoinPoint){
AdminLog adminLog=new AdminLog();
// 1 获取正在执行的方法的对象
MethodSignature signature=(MethodSignature)proceedingJoinPoint.getSignature();
Method method=signature.getMethod();
// 2通过方法对象获取方法上的注解对象
ServiceLog annotation=method.getAnnotation(ServiceLog.class);
// 3获取注解中的值
String value=annotation.value();
// 1获取requeset
ServletRequestAttributes requestAttributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request=requestAttributes.getRequest();
// 2通过request和工具类得到ip
String ip= IPKit.getIpAddrByRequest(request);
HttpSession session=null;
CmfzAdmin admin=null;
try {
// 放行方法
Object proceed = proceedingJoinPoint.proceed();
// 3.通过request可以得到session
session = request.getSession();
// 4.通过session可以得到session中的信息 id 和 用户名
admin = (CmfzAdmin) session.getAttribute("admin");
adminLog.setLog_action(value);
adminLog.setLog_date(new Date());
adminLog.setLog_ip(ip);
adminLog.setAdmin_id(admin.getId());
adminLog.setAdmin_username(admin.getUsername());
adminLog.setLog_result("成功");
//添加数据库
adminLogService.insert(adminLog);
logger.info("操作成功:"+adminLog);
return proceed;
} catch (Throwable throwable) {
logger.error("操作失败");
return null;
}
}
}