1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 使用Spring AOP自定义注解方式实现用户操作日志记录

使用Spring AOP自定义注解方式实现用户操作日志记录

时间:2022-08-14 08:05:30

相关推荐

使用Spring AOP自定义注解方式实现用户操作日志记录

1,开发环境

操作系统:Windows 7

JDK:1.8.0_161

Eclipse:Mars.2 Release (4.5.2)

2,自定义注解类UserLog

@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documentedpublic @interface UserLog {/** 要执行的操作内容比如:用户:XXX登录成功 **/public String operationContent() default "";}

3,日志处理切面UserLogAspect

这里使用的是后通知,当业务代码执行完成后,再执行日志保存。

@Aspect@Componentpublic class UserLogAspect {@Autowiredprivate ILogSysUserService logSysUserService;//Controller层切点 @Pointcut("@annotation(mon.annotation.UserLog)")public void controllerAspect() {}/** * 前置通知 用于拦截Controller层记录用户的操作 * * @param joinPoint 切点 */ @SuppressWarnings("rawtypes")@After("controllerAspect()")public void doAfter(JoinPoint joinPoint) {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();HttpSession session = request.getSession();//读取session中的用户SysAccount account = (SysAccount) session.getAttribute("account");if(null != account){//获取请求ipString 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 operationUrl = request.getServletPath();String operationContent = "";for (Method method : methods) {if (method.getName().equals(methodName)) {Class[] clazzs = method.getParameterTypes();if (clazzs.length == arguments.length) {//凡是加了UserLog注解的方法都记录日志if(null != method.getAnnotation(UserLog.class)){operationContent = method.getAnnotation(UserLog.class).operationContent();//获取用户请求方法的参数并序列化为JSON格式字符串 Map<String,Object> nameAndArgs = null;if(null != joinPoint.getArgs() && joinPoint.getArgs().length > 0) {//获取参数名称和值 nameAndArgs = getParameMap(joinPoint);}SysUserLogDTO log = new SysUserLogDTO();log.setUserId(account.getAccountId());log.setUserName(account.getName());log.setUserIp(ip);log.setOperationUrl(operationUrl);log.setOperationContent(operationContent);log.setParameMap(nameAndArgs);logSysUserService.saveSysUserLog(log);break;}}}}}catch(Exception e) {LoggerUtils.error("记录用户操作日志失败!", e);}}}/*** @Title: getParameMap* @Description: 获取参数的名称和值* @author: 施勇* @date: 10月3日 下午3:12:26* @param: @param joinPoint* @param: @return* @return: Map<String,Object>* @throws*/public Map<String,Object> getParameMap(JoinPoint joinPoint){Map<String, Object> map = new HashMap<String, Object>();Object[] args = joinPoint.getArgs(); // 参数值String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames(); // 参数名for(int i=0;i<argNames.length;i++){if("response".equals(argNames[i]) || "request".equals(argNames[i]) || "pwd".equals(argNames[i])){continue;}else{map.put(argNames[i], args[i]);}}return map;}}

getParameMap()这个方法是用于获取用户请求中的参数,只需要保存业务相关的参数就可以了,所以将request和response过滤掉了,同时也不保存用户登录时的密码。对这个参数Map在保存到数据库中的时候可以转换成JSONString,这样方便查看。

4,使用注解

在需要记录日志的地方加上注解

@RequestMapping("/doLogin")@ResponseBody@UserLog(operationContent="登录系统")public ResultBean doLogin(String loginName, String pwd, HttpServletRequest request,HttpServletResponse response){}

这里重点是AOP切面保存用户操作日志,其他AOP相关配置就不重复说了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。