数据库字段
建表语句
CREATE TABLE log_table
(log_id
int(11) NOT NULL auto_increment COMMENT ‘主键’,log_ipAddress
varchar(64) default NULL COMMENT ‘请求的IP地址’,log_createtime
varchar(64) default NULL COMMENT ‘时间’,log_moduleName
varchar(128) default NULL COMMENT ‘模块名称’,log_desc
varchar(128) default NULL COMMENT ‘功能’,log_type
varchar(32) default NULL COMMENT ‘操作类型’,log_methodName
varchar(128) default NULL COMMENT ‘请求的方法名’,log_params
varchar(1000) default NULL COMMENT ‘请求的参数’,log_paramter
varchar(2000) default NULL COMMENT ‘请求的参数’,
PRIMARY KEY (log_id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=‘操作日志表’;
配置application-aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 配置包扫描器,扫描@Service主键的类[此处只扫描后台的包] -->
<context:component-scan base-package="com.kindergarten.log"></context:component-scan>
<!-- 定义操作日志切面 -->
<bean id="logAspect" class="com.kindergarten.log.LogAopAspect"></bean>
<!-- 通知Spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->
<aop:aspectj-autoproxy proxy-target-class="true">
<aop:include name="logAspect"/>
</aop:aspectj-autoproxy>
实体类
package com.kindergarten.log;
public class Logentity {
/**
* 主键
**/
private String logId = "";
/**
* 请求的IP地址
**/
private String logIpAddress = "";
/**
* 时间
**/
private String logCreatetime = "";
/**
* 模块名称
**/
private String logModulename = "";
/**
* 功能
**/
private String logDesc = "";
/**
* 操作类型
**/
private String logType = "";
/**
* 请求的方法名
**/
private String logMethodname = "";
/**
* 请求的参数
**/
private String logParams = "";
/**
* 请求的参数
**/
private String logParamter = "";
public String getLogId() {
return logId;
}
public void setLogId(String logId) {
this.logId = logId;
}
public String getLogIpAddress() {
return logIpAddress;
}
public void setLogIpAddress(String logIpAddress) {
this.logIpAddress = logIpAddress;
}
public String getLogCreatetime() {
return logCreatetime;
}
public void setLogCreatetime(String logCreatetime) {
this.logCreatetime = logCreatetime;
}
public String getLogModulename() {
return logModulename;
}
public void setLogModulename(String logModulename) {
this.logModulename = logModulename;
}
public String getLogDesc() {
return logDesc;
}
public void setLogDesc(String logDesc) {
this.logDesc = logDesc;
}
public String getLogType() {
return logType;
}
public void setLogType(String logType) {
this.logType = logType;
}
public String getLogMethodname() {
return logMethodname;
}
public void setLogMethodname(String logMethodname) {
this.logMethodname = logMethodname;
}
public String getLogParams() {
return logParams;
}
public void setLogParams(String logParams) {
this.logParams = logParams;
}
public String getLogParamter() {
return logParamter;
}
public void setLogParamter(String logParamter) {
this.logParamter = logParamter;
}
}
Service接口
package com.kindergarten.log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.kindergarten.mapper.LogMapper;
@Service
public class LogServiceImpl implements LogService{
@Autowired
private LogMapper logMapper;
/**
*add log
*/
@Override
public void insertlog(Logentity logentity){
logMapper.insertlog(logentity);
}
}
Service
package com.kindergarten.log;
public interface LogService {
/**
*add log
*/
public void insertlog(Logentity logentity);
}
日志切面
package com.kindergarten.log;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
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.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSON;
import com.kindergarten.util.DateUtil;
import com.kindergarten.util.IpAddress;
import java.util.HashMap;
@Aspect
@Component
public class LogAopAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(LogAopAspect.class);
@Autowired
private LogService logService;
/**
* Controller层切点
*/
@Pointcut("@annotation(com.kindergarten.log.LogAopPointcut)")
public void aopPoint() {
}
/**
* 切面 配置通知
*/
@AfterReturning("aopPoint()")
public void saveSysLog(JoinPoint joinPoint) {
//保存日志
Logentity log = new Logentity();
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
//获取操作
LogAopPointcut logAopPointcut = method.getAnnotation(LogAopPointcut.class);
//--------------------
if (logAopPointcut != null) {
//模块名称
log.setLogModulename(logAopPointcut.logModulename());
//功能
log.setLogDesc(logAopPointcut.logDesc());
//操作类型
String index = logAopPointcut.logType().getIndex();
String name = logAopPointcut.logType().getLogname();
log.setLogType(name);
}
//时间
log.setLogCreatetime(DateUtil.getDate_YMDHMS_S());
//--------------------
//获取请求的方法名
String methodName = method.getName();
log.setLogMethodname(methodName);
//--------------------
//请求的参数
Object[] args = joinPoint.getArgs();
//将参数所在的数组转换成json
String params = JSON.toJSONString(args);
log.setLogParams(params);
//--------------------
//--------------------
//创建参数名称实例
LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
String[] paramterNames = discoverer.getParameterNames(method);
//传递给方法的参数数据
Map<String, Object> paramsMap = new HashMap<String, Object>();
for (int i = 0; i < paramterNames.length; i++) {
Object o = args[i];
if(o instanceof String || o instanceof String[]) {
paramsMap.put(paramterNames[i], o);
}else {
continue;
}
}
String paramter = JSON.toJSONString(paramsMap);
log.setLogParamter(paramter);
//--------------------
//获取用户ip地址
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
log.setLogIpAddress(IpAddress.getIpAddress(request));
//--------------------
// //获取用户名
// sysLog.setUsername(ShiroUtils.getUserEntity().getUsername());
//调用service保存log实体类到数据库
logService.insertlog(log);
}
}
定义操作日志类别
package com.kindergarten.log;
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;
/**
* 1.CONSTRUCTOR:用于描述构造器
* 2.FIELD:用于描述域
* 3.LOCAL_VARIABLE:用于描述局部变量
* 4.METHOD:用于描述方法
* 5.PACKAGE:用于描述包
* 6.PARAMETER:用于描述参数
* 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
* */
@Target({ElementType.METHOD})//方法上
/**
* 1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
* 2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
* 3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
* */
@Retention(RetentionPolicy.RUNTIME)
/**
* Documented注解表明这个注释是由 javadoc记录的,在默认情况下也有类似的记录工具。
* 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分
* */
@Documented
public @interface LogAopPointcut
{
public abstract String logModulename();
public abstract String logDesc();
public abstract log_Type logType();
public static enum log_Type
{
SELECT,ADD,UPDATE,DELETE,EXPORT,IMPORT;
private String logname;
private String index;
public String getLogname() {
return this.name();
}
public String getIndex() {
return String.valueOf(this.ordinal()+1);
}
}
}
在需要记录的方法上使用自定义的@LogAopPointcut
例:
例:@LogAopPointcut(logModulename = “学员模块”,logDesc = “条件查询”,logType = log_Type.SELECT)
@LogAopPointcut(logModulename = “学员模块”,logDesc = “条件删除”,logType = log_Type.SELECT)
/** 条件查询 */
@RequestMapping(value = "/findStudent", produces = "application/json;charset=UTF-8")
@ResponseBody
@LogAopPointcut(logModulename = "学员模块",logDesc = "条件查询",logType = log_Type.SELECT)
public String findStudent(String starttime, String endtime, String id, String name, String age) {
List<StudentEntity> list = studentService.findStudent(starttime, endtime, id, name, age);
String json = JSONArray.toJSONStringWithDateFormat(list, "yyyy-MM-dd HH:mm:ss");
return json;
}