文章目录
一、数据库与表结构
1、日志表信息描述sysLog
2、sql语句
CREATE TABLE sysLog(
id VARCHAR(32) PRIMARY KEY,
visitTime TIMESTAMP,
username VARCHAR(50),
ip VARCHAR(30),
url VARCHAR(50),
executionTime INT,
method VARCHAR(200)
);
INSERT INTO syslog(visitTime,username,ip,url,executionTime,method) VALUES('2020-08-16 07:34:37','username','ip','url',1,'methodName')
DELIMITER $$
CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `orcl`.`id_sysLog_trigger` BEFORE INSERT
ON `orcl`.`sysLog`
FOR EACH ROW BEGIN
SET new.id=REPLACE(UUID(),'-',''); -- 触发器执行的逻辑
END$$
DELIMITER ;
3、实体类
public class SysLog {
private String id;
private Date visitTime;
private String visitTimeStr;
private String username;
private String ip;
private String url;
private Long executionTime;
private String method;
public String getVisitTimeStr() {
if (visitTime!=null){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
visitTimeStr = sdf.format(visitTime);
}
return visitTimeStr;
}
}
二、基于AOP的日志处理(写入)
位置
1、创建切面类处理日志
@Component
@Aspect
public class LogAop {
@Autowired
private HttpServletRequest request;
@Autowired
private ISysLogService sysLogService;
private Date visitTime;//开始的时间
private Class clazz;//访问的类
private Method method;//访问的方法
//前置通知:主要获取开始时间,执行的类时哪一个,执行的是哪一个方法
@Before("execution(* com.itheima.ssm.controller.*.*(..))")
public void doBefore(JoinPoint jp) throws NoSuchMethodException {
//第一次访问时间
visitTime = new Date();
//具体要访问的类
clazz=jp.getTarget().getClass();
//获取方法
/*
先获取访问名称,通过类反射得到method
*/
String methodName = jp.getSignature().getName();//获取访问方法的名称
Object[] args = jp.getArgs();//获取方法的参数
if (args==null||args.length==0){
method = clazz.getMethod(methodName);//只能获取无参数的方法
}else{
Class[] classArgs = new Class[args.length];
for (int i = 0; i <args.length ; i++) {
classArgs[i] = args[i].getClass();
}
clazz.getMethod(methodName,classArgs);
}
}
//前置通知
@After("execution(* com.itheima.ssm.controller.*.*(..))")
public void doAfter(JoinPoint jp) throws Exception {
//获取访问时长
long time = new Date().getTime()-visitTime.getTime();
//获取url
/*
涉及到反射和注解
*/
String url = null;
if(clazz!=null&&method!=null&&clazz!=LogAop.class){
//1.获取类上的@RequestMapping("/orders")
RequestMapping classAnnotation = (RequestMapping)clazz.getAnnotation(RequestMapping.class);
if(classAnnotation!=null){
String[] classValue = classAnnotation.value();
//2.获取方法上的@RequestMapping(xxx)
RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
if(methodAnnotation!=null){
String[] methodValue = methodAnnotation.value();
url = classValue[0]+methodValue[0];
//获取访问的ip地址
/*
1、web.xml中配置
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
2、在本类中注入
@Autowired
private HttpServletRequest request;
*/
String ip = request.getRemoteAddr();
//获取操作者
/*
从上下文中获取了当前登录的用户
*/
SecurityContext context = SecurityContextHolder.getContext();
User user = (User) context.getAuthentication().getPrincipal();
String username = user.getUsername();
//将日志封装到log对象
SysLog sysLog = new SysLog();
sysLog.setUsername(username);
sysLog.setIp(ip);
sysLog.setUrl(url);
sysLog.setVisitTime(visitTime);
sysLog.setExecutionTime(time);
sysLog.setMethod("[类名]"+clazz.getName()+"[方法名]"+method.getName());
sysLogService.save(sysLog);
}
}
}
}
}
分析:在切面类中我们需要获取登录用户的username,还需要获取ip地址,我们怎么处理?
username 获取
SecurityContextHolder获取
ip地址获取
ip地址的获取我们可以通过request.getRemoteAddr()方法获取到。
在Spring中可以通过RequestContextListener来获取request或session对象。
2、ISysLogDao
public interface ISysLogDao {
@Insert("insert into syslog(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")
void save(SysLog sysLog) throws Exception;
}
二、基于AOP的日志处理(读取)
1、页面syslog-list.jsp
aside.jsp
syslog-list.jsp页面
2、SysLogController
@Controller
@RequestMapping("/sysLog")
public class SysLogController {
@Autowired
private ISysLogService sysLogService;
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
ModelAndView mv = new ModelAndView();
List<SysLog> sysLogList = sysLogService.findAll();
mv.setViewName("syslog-list");
mv.addObject("sysLogs",sysLogList);
return mv;
}
}
3、SysLogServiceImpl
@Service
@Transactional
public class SysLogServiceImpl implements ISysLogService {
@Autowired
private ISysLogDao sysLogDao;
@Override
public void save(SysLog sysLog) throws Exception {
sysLogDao.save(sysLog);
}
@Override
public List<SysLog> findAll() throws Exception {
return sysLogDao.findAll();
}
}
4、ISysLogDao
public interface ISysLogDao {
@Insert("insert into syslog(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")
void save(SysLog sysLog) throws Exception;
@Select("Select * from syslog order by visitTime desc")
List<SysLog> findAll() throws Exception;
}