1.需求分析
通过AOP方法实现用户对网页的访问记录,即实现“某用户于什么时间通过什么ip访问了什么接口方法,访问的时长为多久”。
2.数据库和表结构设计
2.1日志表信息描述sysLog
| 字段名称 | 字段类型 | 字段描述 |
| id | varchar | 主键uuid |
| visit_time | datetime | 访问时间 |
| user_name | varchar | 操作者用户名 |
| ip | varchar | 访问ip |
| url | varchar | 访问资源url |
| execution_time | int | 执行时长 |
| method | varchar | 访问方法 |
2.2实体类
@data
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;
}
3.基于AOP日志处理
3.1创建切面类处理日志
@Component
@Aspect
public class LogAop {@Autowiredprivate HttpServletRequest request;@Autowiredprivate ISysLogService sysLogService;private Date startTime; // 访问时间private Class executionClass;// 访问的类private Method executionMethod; // 访问的方法// 主要获取访问时间、访问的类、访问的方法@Before("execution(* com.test.ssm.controller.*.*(..))")public void doBefore(JoinPointjp) throws NoSuchMethodException, SecurityException {// 访问时间startTime=newDate();// 获取访问的类executionClass=jp.getTarget().getClass();// 获取访问的方法String methodName=jp.getSignature().getName(); // 获取访问的方法的名称// 获取访问的方法的参数Object[] args=jp.getArgs();if (args==null||args.length==0) {// 无参数 // 只能获取无参数方法executionMethod=executionClass.getMethod(methodName);} else {// 有参数,就将args中所有元素遍历,获取对应的Class,装入到一个Class[]Class[] classArgs=new Class[args.length];for (int i=0; i<args.length; i++) {classArgs[i] =args[i].getClass();}// 获取有参数方法executionMethod=executionClass.getMethod(methodName, classArgs); }}// 主要获取日志中其它信息,时长、ip、url...@After("execution(* com.test.ssm.controller.*.*(..))")public void doAfter(JoinPoint jp) throws Exception {// 获取类上的@RequestMapping对象if (executionClass!=SysLogController.class) {RequestMapping classAnnotation = (RequestMapping) executionClass.getAnnotation(RequestMapping.class);if (classAnnotation!=null) {// 获取方法上的@RequestMapping对象 RequestMapping methodAnnotation = executionMethod.getAnnotation(RequestMapping.class);if (methodAnnotation!=null) {Stringurl=""; // 它的值应该是类上的@RequestMapping的value+方法上的@RequestMapping的valueurl=classAnnotation.value()[0] +methodAnnotation.value()[0];SysLog sysLog=new SysLog();// 获取访问时长Long executionTime=new Date().getTime() -startTime.getTime();// 将sysLog对象属性封装sysLog.setExecutionTime(executionTime);sysLog.setUrl(url);// 获取ipString ip=request.getRemoteAddr();sysLog.setIp(ip);// 可以通过securityContext获取,也可以从request.getSession中获取SecurityContext context=SecurityContextHolder.getContext();//request.getSession().getAttribute("SPRING_SECURITY_CONTEXT")Stringusername= ((User)(context.getAuthentication()
.getPrincipal())).getUsername();sysLog.setUsername(username);sysLog.setMethod("[类名]"+executionClass.getName()
+"[方法名]"+executionMethod.getName());sysLog.setVisitTime(startTime);// 调用Service,调用dao将sysLog insert数据库sysLogService.save(sysLog);}}}
}
在切面类中还需要获取username和ip地址:
username可以通过SecurityContextHolder获取;
ip地址可以通过request.getRemoteAddr()方法获取到。在Spring中可以通过RequestContextListener来获取request或session对象。
3.2 控制层
@RequestMapping("/sysLog")
@Controller
public class SysLogController {@Autowiredprivate ISysLogService sysLogService;@RequestMapping("/findAll.do")public ModelAndView findAll() throws Exception {ModelAndView mv=new ModelAndView();List<SysLog> sysLogs=sysLogService.findAll();mv.addObject("sysLogs", sysLogs);mv.setViewName("syslog-list");return mv;}
}
3.3 业务层
@Service
@Transactional
public class SysLogServiceImpl implements ISysLogService {@Autowiredprivate ISysLogDao sysLogDao;@Override public void save(SysLog log) throws Exception {sysLogDao.save(log);}@Overridepublic List<SysLog> findAll() throws Exception {return sysLogDao.findAll();}
}
3.4 dao层
public interface ISysLogDao {@Select("select * from syslog")@Results({@Result(id=true,column="id",property="id"),@Result(column="visitTime",property="visitTime"),@Result(column="ip",property="ip"),@Result(column="url",property="url"),@Result(column="executionTime",property="executionTime"),@Result(column="method",property="method"),@Result(column="username",property="username")})public List<SysLog> findAll() throws Exception;@Insert("insert into syslog(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")public void save(SysLoglog) throws Exception;
}