这是我参与 8 月更文挑战的第 23 天,活动详情查看: 8月更文挑战
6. 自定义操作日志记录的注解
在config目录下新建一个名为OperLog的Annotation文件。
package com.tjm.config;
import java.lang.annotation.*;
/*
自定义操作日志注解
@Author tjm
*/
// 注解放置的目标位置,METHOD是可注解在方法级别上
@Target(ElementType.METHOD)
// 注解在哪个阶段执行
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperLog {
String operModul() default ""; //操作模块
String operType() default ""; //操作类型
String operDesc() default ""; //操作说明
}
自定义了一个注解为@OperLog,之后在我们想要记录的controller中的方法前,就可以叫上这个注解。这样,只要有用户调用了这个方法,就会被记录下来。
7. 自定义操作日志切面类(核心)
同样在config目录下,新建一个OperLogAspect.java,代码如下:
package com.tjm.config;
import com.tjm.pojo.OperationLog;
import com.tjm.pojo.User;
import com.tjm.service.OperationLogService;
import org.apache.shiro.SecurityUtils;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.Date;
@Aspect
@Component
public class OperLogAspect {
private final static Logger log = org.slf4j.LoggerFactory.getLogger(LogAsPect.class);
@Autowired
private OperationLogService operationLogService;
//表示匹配带有自定义注解的方法
@Pointcut("@annotation(com.tjm.config.OperLog)")
public void operLogPoinCut()
{
}
@AfterReturning(value = "operLogPoinCut()",returning = "keys")
public void saveOperLog(JoinPoint joinPoint, Object keys) {
//获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//从获取RequestAttributes中获取HttpServletRequest信息
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
OperationLog operlog = new OperationLog();
try{
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取操作
OperLog opLog = method.getAnnotation(OperLog.class);
if (opLog != null) {
String operModul = opLog.operModul();
String operType = opLog.operType();
String operDesc = opLog.operDesc();
operlog.setOper_modul(operModul); // 操作模块
operlog.setOper_type(operType); // 操作类型
operlog.setOper_desc(operDesc); // 操作描述
}
//从session中获取当前登录的人id
User user = (User) SecurityUtils.getSubject().getPrincipal();
String username = user.getUsername();
operlog.setUsername(username);
//设置时间
Timestamp creat_time = new java.sql.Timestamp(new Date().getTime());
operlog.setOper_creat_time(creat_time);
operationLogService.insertOperLog(operlog);
}catch (Exception e){
}
}
}
捕捉异常:
catch (Exception e){
//实际上出现异常后,也可以采取一些操作,比如添加一个异常日志管理,这里暂时就没实现了
}
8. 测试
在任一个Controller文件中的方法前添加一个@OperLog,,如在查询所有用户方法前添加**@OperLog(operModul = "用户管理",operType = "查询",operDesc = "查询所有用户")**。
operModul 、operType、operDesc 对应我们OperLog.Annotation中设定的操作模块、操作类型和操作描述。
//查询所有用户,返回列表界面
@RequestMapping("/users")
@Log
@OperLog(operModul = "用户管理",operType = "查询",operDesc = "查询所有用户")
public String list(Model model){
Collection<User> users = userService.queryUserList();
//将结果放在请求中
model.addAttribute("users",users);
return "person";
}
执行方法后,可以看到数据库中新增数据的更新。