aop切面记录操作日志
新增操作日志po类【SysOperationLog.java】
package com.dc.pojo;
import com.wordnik.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
public class SysOperationLog implements Serializable {
@ApiModelProperty(value = "")
private int operationlog_id;
@ApiModelProperty(value = " 操作人id")
private int user_id;
@ApiModelProperty(value = " 操作人姓名")
private String user_name;
@ApiModelProperty(value = " 操作人账号")
private String user_account;
@ApiModelProperty(value = " 操作时间")
private Date date;
@ApiModelProperty(value = " 操作内容")
private String content;
@ApiModelProperty(value = " 操作类型")
private String type;
@ApiModelProperty(value = " 操作模块")
private String module;
@ApiModelProperty(value = " 请求ip ")
private String request_ip;
@ApiModelProperty(value = " 请求前数据 ")
private String param_before;
@ApiModelProperty(value = " 请求后数据")
private String param_after;
@ApiModelProperty(value = " 请求参数")
private String request_params;
@ApiModelProperty(value = " 请求方法")
private String request_method;
public int getOperationlog_id() {
return operationlog_id;
}
public void setOperationlog_id(int operationlog_id) {
this.operationlog_id = operationlog_id;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_account() {
return user_account;
}
public void setUser_account(String user_account) {
this.user_account = user_account;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
public String getRequest_ip() {
return request_ip;
}
public void setRequest_ip(String request_ip) {
this.request_ip = request_ip;
}
public String getParam_before() {
return param_before;
}
public void setParam_before(String param_before) {
this.param_before = param_before;
}
public String getParam_after() {
return param_after;
}
public void setParam_after(String param_after) {
this.param_after = param_after;
}
public String getRequest_params() {
return request_params;
}
public void setRequest_params(String request_params) {
this.request_params = request_params;
}
public String getRequest_method() {
return request_method;
}
public void setRequest_method(String request_method) {
this.request_method = request_method;
}
}
新增操作日志新增接口【SysOperationLogDao.java】
package com.dc.mapper;
import com.dc.pojo.SysOperationLog;
public interface SysOperationLogDao {
int insert(SysOperationLog operationLog);
}
新增操作日志新增sqlMapper【SysOperationLogMapper.xml】
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dc.mapper.SysOperationLogDao">
<insert id="insert" parameterType="com.dc.pojo.SysOperationLog" useGeneratedKeys="true" keyProperty="user_id">
insert into t_sys_operationlog
(user_id, user_name, user_account, date, content, type, module, request_ip, param_before, param_after, request_params, request_method)
values
(#{user_id}, #{user_name}, #{ user_account}, now(), #{ content}, #{type}, #{ module}, #{ request_ip}, #{ param_before}, #{param_after}, #{ request_params}, #{request_method})
</insert>
</mapper>
新增权限菜单枚举类【RoleMenuEnum.java】,内容和菜单表相对应,用于切面记录操作模块
package com.dc.base.contants;
public enum RoleMenuEnum {
NO_2(2,"Swagger")
,NO_203(203,"角色管理")
, NO_204(204,"用户管理")
, NO_102(102,"登录日志")
, NO_103(103,"操作日志")
;
int code;
String describe;
RoleMenuEnum(int code, String describe){
this.code=code;
this.describe=describe;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
}
新增自定义切面注解类【AopOperation.java】
package com.dc.base.aop;
import com.dc.base.contants.RoleMenuEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)//标记注解用于方法
@Retention(RetentionPolicy.RUNTIME)//可以反射获得注解参数
public @interface AopOperation {
/**
* @title:<h3> 描述信息 <h3>
* @author: Enzo
* @date: 2018-11-19 15:44
* @params []
* @return java.lang.String
**/
String desc() default "";
/**
* @title:<h3> 操作类型 <h3>
* @author: Enzo
* @date: 2018-11-19 15:44
* @params []
* @return java.lang.String
**/
String type();
/**
* @title:<h3> 权限菜单 <h3>
* @author: Enzo
* @date: 2018-11-19 15:44
* @params []
* @return com.dc.base.em.RoleMenuEnum
**/
RoleMenuEnum menu();
/**
* @title:<h3> 是否记录操作日志 <h3>
* @author: Enzo
* @date: 2018-11-19 15:44
* @params []
* @return boolean
**/
boolean saveLog() default true;
}
引入aop切面maven配置
<!--aop切面-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
springMVC配置文件添加aop配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 全局扫描-->
<context:component-scan base-package="com.dc.controller,com.dc.base.controller,com.dc.base.aop"></context:component-scan>
<!-- Aop注解aspectj -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
在【BaseModel.java】中添加成员变量aopMesg和aop_num,用于记录切面信息
@ApiModelProperty("aop保存参数")
private String aop_mesg="";
public String getAop_mesg() {
return aop_mesg;
}
public void setAop_mesg(String aop_mesg) {
this.aop_mesg = aop_mesg;
}
新增切面类【OperatorAspect.java】,在后置方法中添加记录操作日志方法
package com.dc.base.aop;
import com.dc.base.contants.BaseContants;
import com.dc.base.contants.ErrorMesgEnum;
import com.dc.base.pojo.BaseModel;
import com.dc.base.pojo.BusinessException;
import com.dc.mapper.SysOperationLogDao;
import com.dc.pojo.SysOperationLog;
import com.dc.pojo.SysUser;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* @author Enzo
* @Description TODO
* @date 2018-11-19 15:46
*/
@Aspect
@Component
public class OperationAspect {
Logger log = Logger.getLogger(OperationAspect.class);
protected HttpServletRequest request;
protected HttpSession session;
protected BaseModel baseModel = new BaseModel();
@Autowired
private SysOperationLogDao operationLogDao;
@Pointcut("execution(* com.dc.controller..*.*(..))")
public void pointCut() {
}
/**
* @return void
* @title:<h3> 前置通知,用于获得请求参数,req,sesssion <h3>
* @author: Enzo
* @date: 2018-11-19 16:11
* @params [joinPoint, operation]
**/
@Before("pointCut()&&@annotation(operation)")
public void doBefore(JoinPoint joinPoint, AopOperation operation)throws Exception {
request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
session = request.getSession();
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
if (args[i].getClass() == BaseModel.class) {
baseModel = (BaseModel) args[i];
}
}
}
/**
* @return void
* @title:<h3> 后置通知,记录操作日志 <h3>
* @author: Enzo
* @date: 2018-11-20 14:03
* @params [joinPoint, operation]
**/
@After("pointCut()&&@annotation(operation)")
public void doAfter(JoinPoint joinPoint, AopOperation operation) {
SysOperationLog operationLog = new SysOperationLog();
operationLog.setRequest_ip(request.getRemoteAddr());
SysUser user = (SysUser) session.getAttribute(BaseContants.LOGIN_USER);
if (user == null) {
throw new BusinessException(ErrorMesgEnum.NO_LOGIN);
}
operationLog.setUser_account(user.getAccount());
operationLog.setUser_id(user.getUser_id());
operationLog.setUser_name(user.getName());
operationLog.setModule(operation.menu().getDescribe());
operationLog.setType(operation.type());
operationLog.setContent(operation.desc() + "|" + baseModel.getAop_mesg());
operationLog.setRequest_method(joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature());
if (operation.saveLog()) {
int count = operationLogDao.insert(operationLog);
if (count == 0) {
throw new BusinessException("新增操作日志失败");
}
}
}
}
在controller各接口添加切面注释,返回前可把主要信息保存在baseModel.aopMesg中
【SysRoleController.java】
@AopOperation(desc = "分页查询列表", type = BaseContants.OPERATION_TYPE.SEARCH, menu = RoleMenuEnum.NO_203)
public BaseModel selectPageRole(BaseModel baseModel) throws Exception {
}
@AopOperation(type = BaseContants.OPERATION_TYPE.ADD, menu = RoleMenuEnum.NO_203)
public BaseModel insertRoleVo(@ModelAttribute SysRoleVo roleVo, BaseModel baseModel) throws Exception {
baseModel.setAop_mesg(roleVo.getRole().getName());
}
@AopOperation(desc = "根据id查询角色信息", type = BaseContants.OPERATION_TYPE.SEARCH, menu = RoleMenuEnum.NO_203)
public BaseModel selectRoleVoByPk(BaseModel baseModel, @PathVariable("pk") int pk) throws Exception {
baseModel.setAop_mesg(pk+"");
}
@AopOperation(type = BaseContants.OPERATION_TYPE.UPDATE, menu = RoleMenuEnum.NO_203)
public BaseModel updateRoleVo(@ModelAttribute SysRoleVo roleVo, BaseModel baseModel) throws Exception {
baseModel.setAop_mesg(roleVo.getRole().getName());
}
@AopOperation(type = BaseContants.OPERATION_TYPE.DELETE, menu = RoleMenuEnum.NO_203)
public BaseModel deleteRole(BaseModel baseModel, @PathVariable("ids") String roleIds) throws Exception {
baseModel.setAop_mesg(roleIds);
}
【SysUserController.java】
@AopOperation(menu = RoleMenuEnum.NO_204, type = BaseContants.OPERATION_TYPE.ADD)
public BaseModel inserUserVo(@ModelAttribute SysUserVo userVo, BaseModel baseModel) throws Exception{
baseModel.setAop_mesg("用户id:" + userVo.getUser().getUser_id() + ",姓名:" + userVo.getUser().getName());
}
@AopOperation(menu = RoleMenuEnum.NO_204, type = BaseContants.OPERATION_TYPE.SEARCH)
public BaseModel selectPageUserVo(BaseModel baseModel) throws Exception {
}
@AopOperation(desc = "根据用户id查询用户信息", type = BaseContants.OPERATION_TYPE.SEARCH, menu = RoleMenuEnum.NO_204)
public BaseModel selectUserVoByPk(@PathVariable("pk") int pk, BaseModel baseModel) throws Exception {
baseModel.setAop_mesg(pk+"");
}
@AopOperation(menu = RoleMenuEnum.NO_204, type = BaseContants.OPERATION_TYPE.UPDATE)
public BaseModel updateUserVo(@ModelAttribute SysUserVo userVo, BaseModel baseModel) throws Exception {
baseModel.setAop_mesg("用户id:" + userVo.getUser().getUser_id() + ",姓名:" + userVo.getUser().getName());
}
@AopOperation(menu = RoleMenuEnum.NO_204, type = BaseContants.OPERATION_TYPE.DELETE)
public BaseModel deleteUser(@PathVariable("userIds") String userIds, BaseModel baseModel) throws Exception {
baseModel.setAop_mesg(userIds);
}
@AopOperation(desc = "重置密码", menu = RoleMenuEnum.NO_204, type = BaseContants.OPERATION_TYPE.UPDATE)
public BaseModel resetPassword(@PathVariable("pk") int pk, BaseModel baseModel) throws Exception {
baseModel.setAop_mesg(pk + "");
}
@AopOperation(desc = "状态切换", menu = RoleMenuEnum.NO_204, type = BaseContants.OPERATION_TYPE.UPDATE)
public BaseModel tiggerState(@PathVariable("pk") int userId, BaseModel baseModel) throws Exception {
baseModel.setAop_mesg(userId+ "");
}