代码较多,请耐心调试
首先oracle数据库表创建语句:
drop table cmu_system_log;
CREATE TABLE CMU_SYSTEM_LOG ();
需要在:Spring-mvc.xml中增加:
pom.xml里面需要导入:
SysLog.java
package com.security.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
/** 要执行的操作类型比如:add操作 **/
public String operationType() default "";
/** 要执行的具体操作比如:添加用户 **/
public String operationName() default "";
}
SystemControllerLog.java
package com.security.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String description() default "";
}
最重要的文件:SystemLogAspect.java
package com.security.annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
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 com.community.service.SystemLogService;
import com.community.util.IpUtil;
import com.oracle.pojo.SystemLog;
import com.oracle.pojo.Users;
@Aspect
@Component
public class SystemLogAspect {
// 使用service注入功能把日志写进数据库中
@Resource
private SystemLogService systemLogService;
private static final Logger logger = LoggerFactory
.getLogger(SystemLogAspect.class);
// Conntroller层的切点
@Pointcut("@annotation(com.security.annotation.SysLog)")
public void controllerAspect() {
}
/**
* 编写后置通知,用于拦截Controller 层记录用户的操作
*
* joinPoint 切点
*/
@After("controllerAspect()")
public void after(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
Users user = (Users) SecurityUtils.getSubject().getPrincipal();
String userName = null;
String userId = null;
if (user != null) {
Subject currentUser = SecurityUtils.getSubject();
userId = currentUser.getSession().getAttribute("_USER_ID")
.toString();
userName = (String) user.getUsername();
}
// 请求的IP
String ip = request.getRemoteAddr();
try {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String operationType = "";
String operationName = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
operationType = method.getAnnotation(SysLog.class)
.operationType();
operationName = method.getAnnotation(SysLog.class)
.operationName();
break;
}
}
}
// 数据库日志
SystemLog log = new SystemLog();
log.setUserId(new Integer(userId));// 登录的用户id
log.setUsername(userName);// 这里需要获取用户名
log.setDescription(operationName);
log.setMethods((joinPoint.getTarget().getClass().getName() + "."
+ joinPoint.getSignature().getName() + "()"));
log.setLogType(operationType);
log.setRequestIp(IpUtil.ipToInt(ip));
log.setExceptioncode(null);
log.setExceptionDetail(null);
log.setParams(null);
log.setTime(new Date());
// 保存数据库
systemLogService.insertSelective(log);
System.out.println("=====controller后置通知成功结束=====");
} catch (Exception e) {
// 记录本地异常日志
logger.error("===后置通知异常===");
logger.error("异常信息:{}", e.getMessage());
}
}
/**
* 异常通知 用于拦截记录异常日志
*/
@AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
Users user = (Users) SecurityUtils.getSubject().getPrincipal();
String userName = null;
String userId = null;
if (user != null) {
Subject currentUser = SecurityUtils.getSubject();
userId = currentUser.getSession().getAttribute("_USER_ID")
.toString();
userName = (String) user.getUsername();
}
// 请求的IP
String ip = request.getRemoteAddr();
String params = "";
if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
params = Arrays.toString(joinPoint.getArgs());
}
try {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String operationType = "error";
String operationName = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
operationType = method.getAnnotation(SysLog.class)
.operationType();
operationName = method.getAnnotation(SysLog.class)
.operationName();
break;
}
}
}
// ====数据库日志=====
SystemLog log = new SystemLog();
log.setUserId(new Integer(userId));// 登录的用户id
log.setUsername(userName);// 这里需要获取用户名
log.setDescription(operationName);
log.setMethods((joinPoint.getTarget().getClass().getName() + "."
+ joinPoint.getSignature().getName() + "()")
+ "." + operationType);
log.setLogType(operationType);
log.setRequestIp(IpUtil.ipToInt(ip));
log.setExceptioncode(null);
log.setExceptionDetail(null);
log.setParams(null);
log.setTime(new Date());
// 保存数据库
systemLogService.insertSelective(log);
System.out.println("=====异常通知结束=====");
} catch (Exception ex) {
// 记录本地异常日志
logger.error("==异常通知异常==");
logger.error("异常信息:{}", ex.getMessage());
}
// 记录本地异常日志
logger.error("异常方法:{}异常代码:{}异常信息:{}参数:{}", joinPoint.getTarget()
.getClass().getName()
+ joinPoint.getSignature().getName(), e.getClass().getName(),
e.getMessage(), params);
}
}
SystemServiceLog.java
package com.security.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemServiceLog {
String description() default "";
}
SytemLogcontroller.java 负责与前端交互
package com.community.controller;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.community.pager.PageInfo;
import com.community.service.SystemLogService;
@Controller
@Scope(value = "prototype")
@RequestMapping(value = "systemlog")
public class SystemLogController extends BaseController {
@Autowired
SystemLogService systemLogService;
/**
* 跳转到日志展示界面 权限控制判断 目前没有增加判断,仅跳转使用
*/
@RequestMapping(value = "tolist")
public ModelAndView tolist(ModelMap map) {
return new ModelAndView("/security/logs/logs");
}
/**
* @param page 页数
* @param rows 每页的数据量
* @param searchvalue 搜索关键字
* @param order 排序
* @param sort 按。。顺序排 ,desc、asc
* @param starttime 开始时间
* @param endtime 结束时间
* @param response 相应信息
* @return
*/
@RequestMapping(value = "list")
@ResponseBody
public Object list(Integer page, Integer rows, String searchvalue,
String order, String sort, String starttime, String endtime,
HttpServletResponse response) {
String value = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// ----非空判断----
if (StringUtils.isNotEmpty(searchvalue)) {
try {
value = URLDecoder.decode(searchvalue, "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
}
Date st = null;
Date et = null;
if (StringUtils.isNotEmpty(starttime)) {
try {
st = sdf.parse(starttime);
} catch (ParseException e) {
e.printStackTrace();
}
}
if (StringUtils.isNoneEmpty(endtime)) {
try {
et = sdf.parse(endtime);
} catch (ParseException e) {
e.printStackTrace();
}
}
// ---获取到登录账户的ID值
Subject currentUser = SecurityUtils.getSubject();
String userId = currentUser.getSession().getAttribute("_USER_ID")
.toString();
PageInfo pageInfo = new PageInfo(page, rows);
Map
int start = (page - 1) * rows;
int end = start + rows;
condition.put("st", st);// 开始时间
condition.put("et", et);// 结束时间
condition.put("start", start);
condition.put("end", end);
condition.put("order", order);// 为空没有使用
condition.put("sort", sort);// 为空没有使用
condition.put("value", value);// 获取到搜索框的值(字符)
condition.put("userId", userId);
condition.put("searchvalue", searchvalue);
pageInfo.setCondition(condition);
systemLogService.findLogs(pageInfo);
return pageInfo;
}
}
systemLogMapper.xml
三个方法:
//插入到数据库
insert into CMU_SYSTEM_LOG
LOG_ID,
USER_ID,
USERNAME,
DESCRIPTION,
METHODS,
LOG_TYPE,
REQUEST_IP,
EXCEPTIONCODE,
EXCEPTION_DETAIL,
PARAMS,
TIME,
#{logId,jdbcType=DECIMAL},
#{userId,jdbcType=DECIMAL},
#{username,jdbcType=VARCHAR},
#{description,jdbcType=VARCHAR},
#{methods,jdbcType=VARCHAR},
#{logType,jdbcType=VARCHAR},
#{requestIp,jdbcType=DECIMAL},
#{exceptioncode,jdbcType=VARCHAR},
#{exceptionDetail,jdbcType=VARCHAR},
#{params,jdbcType=VARCHAR},
#{time,jdbcType=TIMESTAMP},
//查询拉取数据(并且有模糊查询和时间判断)
//计算数据的条数
最后 最重要的是给你需要插入数据库的接口增加:@SysLog(operationType="submitLogin",operationName="代理商登录") //举例
前端jsp使用的是easyUI框架:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>