1. 创建表
序号 | 字段名称 | 字段类型 | 字段描述 |
---|---|---|---|
1 | id | int(11) | 主键,自增长 |
2 | visitTime | datetime | 访问时间 |
3 | userName | varchar(50) | 操作者用户名 |
4 | ip | varchar(50) | 访问 ip |
5 | url | varchar(50) | 访问资源 url |
6 | executionTime | int(11) | 执行时长 |
7 | method | varchar(255) | 访问方法 |
DROP TABLE IF EXISTS `syslog`;
CREATE TABLE `syslog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`visitTime` datetime DEFAULT NULL,
`userName` varchar(50) DEFAULT NULL,
`ip` varchar(50) DEFAULT NULL,
`url` varchar(50) DEFAULT NULL,
`executionTime` int(11) DEFAULT NULL,
`method` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 基于 Spring AOP 的日志处理
2.1 实体类
/**
* 日志实体类
*/
public class SysLog {
private Integer id; // 主键
private Date visitTime; // 访问时间
private String visitTimeStr; // 访问时间字符串
private String username; // 操作者用户名
private String ip; // 访问 ip
private String url; // 访问资源 url
private Long executionTime; // 执行时长
private String method; // 访问方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getVisitTime() {
return visitTime;
}
public void setVisitTime(Date visitTime) {
this.visitTime = visitTime;
}
public String getVisitTimeStr() {
if(visitTime != null) {
visitTimeStr = DateUtils.date2String(visitTime,"yyyy-MM-dd HH:mm:ss");
}
return visitTimeStr;
}
public void setVisitTimeStr(String visitTimeStr) {
this.visitTimeStr = visitTimeStr;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Long getExecutionTime() {
return executionTime;
}
public void setExecutionTime(Long executionTime) {
this.executionTime = executionTime;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public String toString() {
return "SysLog{" +
"id=" + id +
", visitTime=" + visitTime +
", visitTimeStr='" + visitTimeStr + '\'' +
", username='" + username + '\'' +
", ip='" + ip + '\'' +
", url='" + url + '\'' +
", executionTime=" + executionTime +
", method='" + method + '\'' +
'}';
}
}
2.2 持久层
public interface SysLogDao {
/**
* 添加日志
* @param sysLog
* @throws Exception
*/
@Insert("insert into syslog(visitTime,userName,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")
void save(SysLog sysLog) throws Exception;
/**
* 查询所有日志
* @return
* @throws Exception
*/
@Select("select * from sysLog")
List<SysLog> findAll() throws Exception;
}
2.3 业务层
public interface SysLogService {
/**
* 添加日志
* @param sysLog
* @throws Exception
*/
void save(SysLog sysLog) throws Exception;
/**
* 查询所有日志
* @return
* @throws Exception
*/
List<SysLog> findAll() throws Exception;
}
@Service
@Transactional
public class SysLogServiceImpl implements SysLogService {
@Autowired
private SysLogDao sysLogDao;
/**
* 查询所有日志
* @return
* @throws Exception
*/
@Override
public List<SysLog> findAll() throws Exception {
return sysLogDao.findAll();
}
/**
* 添加日志
* @param sysLog
* @throws Exception
*/
@Override
public void save(SysLog sysLog) throws Exception {
sysLogDao.save(sysLog);
}
}
2.4 控制层
@Controller
@RequestMapping("/sysLog")
public class SysLogController {
@Autowired
private SysLogService sysLogService;
/**
* 查询所有日志
*
* @return
* @throws Exception
*/
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
ModelAndView mv = new ModelAndView();
List<SysLog> sysLogList = sysLogService.findAll();
mv.addObject("sysLogs", sysLogList);
mv.setViewName("syslog-list");
return mv;
}
}
2.5 切面类
@Component
@Aspect
public class LogAop {
@Autowired
private HttpServletRequest request;
@Autowired
private SysLogService sysLogService;
private Date visitTime; //开始时间
private Class clazz; //访问的类
private Method method; //访问的方法
private Long time; // 访问时长
private String username; // 访问用户名
private String url; // 访问的 url
private String ip; // 访问的 ip
/**
* 前置通知:获取开始时间,访问的类,访问的方法
*/
@Before("execution(* com.zt.controller.*.*(..))")
public void doBefore(JoinPoint jp) throws NoSuchMethodException {
// 获取开始时间
visitTime = new Date();
// 获取访问的类
clazz = jp.getTarget().getClass();
// 获取访问的方法名
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();
}
// 获取有参方法
method = clazz.getMethod(methodName, classArgs);
}
}
/**
* 后置通知:获取访问时长,访问的 url,访问的 ip, 访问的用户名,以及添加日志
*/
@After("execution(* com.zt.controller.*.*(..))")
public void doAfter() throws Exception {
// 获取访问时长
time = new Date().getTime() - visitTime.getTime();
if (clazz != null && method != null && clazz != LogAop.class) {
// 获取类上的 @RequestMapping("xxx")
RequestMapping classAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
if (classAnnotation != null) {
String[] classValue = classAnnotation.value();
// 获取方法上的 @RequestMapping("xxx")
RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
if (methodAnnotation != null) {
String[] methodValue = methodAnnotation.value();
// 获取访问的 url
url = classValue[0] + methodValue[0];
// 获取访问的 ip
ip = request.getRemoteAddr();
SecurityContext context = SecurityContextHolder.getContext();
User user = (User) context.getAuthentication().getPrincipal();
// 获取访问的用户名
username = user.getUsername();
// 将日志相关信息封装到 SysLog 对象
SysLog sysLog = new SysLog();
sysLog.setExecutionTime(time);
sysLog.setIp(ip);
sysLog.setMethod("[类名] " + clazz.getName() + "[方法名] " + method.getName());
sysLog.setUrl(url);
sysLog.setUsername(username);
sysLog.setVisitTime(visitTime);
// 调用 Service 完成操作
sysLogService.save(sysLog);
}
}
}
}
}
2.6 JSP 页面
在 pages 包中创建 syslog-list.jsp