博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring_AOP 记录系统关键操作日志用法
阅读量:6182 次
发布时间:2019-06-21

本文共 11529 字,大约阅读时间需要 38 分钟。

问题:

  系统需要记录用户的关键操作日志,以便后期的系统维护,方便的查看问题,及时排除

 

分析:

  (1)保存字段:作为一个日志记录功能,首先数据库新建一张表保存用户的操作关键字段,

          用户名,ip,操作描述,时间,日志id

  (2)采用技术:

      第一种:新建一个日志业务实现,在操作发生时进行联动

          缺点是耦合太紧密,无用代码增多,后期代码臃肿,改动时地方分散,不利于维护

      第二种:使用spring 的 aop 技术进行切面切入

          由于本身系统结构不规范,参数,方法名没有一致的样式,使用正则匹配方法名不是很方便

          本身日志记录也只是记录关键操作,api全部切入的话,就不需要这个功能了

          必须有针对性的记录关键操作日志

      第三种:使用spring 的 aop 技术切到自定义注解上,针对不同注解标志进行参数解析,记录日志

          缺点是要针对每个不同的注解标志进行分别取注解标志,获取参数进行日志记录输出

         

解决:

  由于本身系统的不规范,个人技术能力的欠缺,目前采用第三种办法进行关键日志的记录

  (1)首先新建 注解类【MethodLog】

package org.triber.portal.service.logAop;import java.lang.annotation.*;/** * 日志切面注解 */@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface MethodLog {    String remark() default "";    String operType() default "0";    // String desc() default "";}

  (2)新建切面实现类【LogService】

package org.triber.portal.service.logAop;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;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 org.triber.common.helper.StringUtil;import org.triber.common.helper.UserUtil;import org.triber.common.model.menu.MenuModel;import org.triber.common.model.user.User;import org.triber.portal.dao.mapper.operateLog.OperateLogMapper;import org.triber.portal.model.area.Area;import javax.servlet.http.HttpServletRequest;import java.lang.reflect.Method;import java.text.SimpleDateFormat;import java.util.Calendar;/** * 日志切面实现 */@Component@Aspectpublic class LogService {    @Autowired    private OperateLogMapper dao;    public LogService() {        System.out.println("Aop");    }    /**     * 切点     */    @Pointcut("@annotation(org.triber.portal.service.logAop.MethodLog)")    public void methodCachePointcut() { }    /**     * 切面     *     * @param point     * @return     * @throws Throwable     */    @Around("methodCachePointcut()")    public Object around(ProceedingJoinPoint point) throws Throwable {        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder                .getRequestAttributes()).getRequest();        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");        Calendar ca = Calendar.getInstance();        String operDate = df.format(ca.getTime());        String ip = getIp(request);        User user = UserUtil.getCurrentUser(request);        String loginName;        String name;        if (user != null) {            loginName = user.getLoginName();        } else {            loginName = "匿名用户";        }        String methodRemark = getMthodRemark(point);        String methodName = point.getSignature().getName();        String packages = point.getThis().getClass().getName();        if (packages.indexOf("$$EnhancerByCGLIB$$") > -1) { // 如果是CGLIB动态生成的类            try {                packages = packages.substring(0, packages.indexOf("$$"));            } catch (Exception ex) {                ex.printStackTrace();            }        }        String operatingcontent = "";        Object[] method_param = null;        Object object;        try {            method_param = point.getArgs(); //获取方法参数            // String param=(String) point.proceed(point.getArgs());            object = point.proceed();        } catch (Exception e) {            // 异常处理记录日志..log.error(e);            throw e;        }        Syslog sysLog = new Syslog();        sysLog.setOptId(org.triber.common.util.StringUtil.getRandNum(11));        sysLog.setLoginId(user.getLoginId());        sysLog.setLoginName(loginName);        sysLog.setIpAddress(ip);        sysLog.setMethodName(packages + "." + methodName);        sysLog.setMethodRemark(methodRemark);        sysLog.setOptDate(operDate);        /**         * 用户操作         */        if("新增用户".equals(methodRemark)){            HttpServletRequest req = (HttpServletRequest) method_param[0];            sysLog.setOperatingcontent("新增用户: 用户名为 " + req.getParameter("userName"));        }        if("删除用户".equals(methodRemark)){            String loginId = (String) method_param[1];            sysLog.setOperatingcontent("删除用户: 用户id为 " + loginId);        }        if("修改用户".equals(methodRemark)){            HttpServletRequest req = (HttpServletRequest) method_param[0];            sysLog.setOperatingcontent("修改用户: 用户名为 " + req.getParameter("loginName"));        }        /**         * 角色操作         */        if("新增角色".equals(methodRemark)){            HttpServletRequest req = (HttpServletRequest) method_param[0];            sysLog.setOperatingcontent("新增角色: 角色名为 " + req.getParameter("roleDesc"));        }        if("删除角色".equals(methodRemark)){            String roleId = (String) method_param[1];            sysLog.setOperatingcontent("新增角色: 角色id为 " + roleId);        }        if("修改角色".equals(methodRemark)){            HttpServletRequest req = (HttpServletRequest) method_param[0];            sysLog.setOperatingcontent("修改角色: 角色名为 " + req.getParameter("roleDesc"));        }        /**         * 菜单操作         */        if("新增菜单".equals(methodRemark)){            MenuModel menuModel = (MenuModel) method_param[0];            sysLog.setOperatingcontent("新增菜单: 菜单名为 " + menuModel.getMenuName());        }        if("删除菜单".equals(methodRemark)){            String menuId = (String) method_param[0];            sysLog.setOperatingcontent("删除菜单: 菜单id为 " + menuId);        }        if("修改菜单".equals(methodRemark)){            MenuModel menuModel = (MenuModel) method_param[0];            sysLog.setOperatingcontent("修改菜单: 菜单名为 " + menuModel.getMenuName());        }        /**         * 部门操作         */        if("新增部门".equals(methodRemark)){            String deptDesc = (String) method_param[1];            sysLog.setOperatingcontent("新增部门: 部门名为 " + deptDesc);        }        if("修改部门".equals(methodRemark)){            String deptDesc = (String) method_param[2];            sysLog.setOperatingcontent("修改部门: 部门名为 " + deptDesc);        }        /**         * 地区操作         */        if("新增地区".equals(methodRemark)){            Area area = (Area) method_param[0];            sysLog.setOperatingcontent("新增地区: 地区名为 " + area.getAreaDscr().trim());        }        if("删除地区".equals(methodRemark)){            String areaId = (String) method_param[0];            sysLog.setOperatingcontent("删除地区: 地区id为 " + areaId);        }        if("修改地区".equals(methodRemark)){            Area area = (Area) method_param[0];            sysLog.setOperatingcontent("修改地区: 地区名为 " + area.getAreaDscr().trim());        }        /**         * 机构操作         */        if("新增机构".equals(methodRemark)){            String isAdd = (String) method_param[1];            if(isAdd.equals("1")){                String addOrgDscrPancy = (String) method_param[5];                sysLog.setOperatingcontent("新增机构: 机构名为 " + addOrgDscrPancy);            }else{                String addOrgDscrPancy = (String) method_param[5];                sysLog.setOperatingcontent("修改机构: 机构名为 " + addOrgDscrPancy);            }        }        if("删除机构".equals(methodRemark)){            String orgId = (String) method_param[3];            sysLog.setOperatingcontent("删除机构: 机构id为 " + orgId);        }        /**         * 空参数         */        if("".equals(methodRemark) || null == methodRemark){            sysLog.setOperatingcontent("操作参数: " + method_param[0]);        }        dao.saveSysLog(sysLog);//        System.out.println("日志实体:"+sysLog.getLoginName()+sysLog.getMethodRemark()+sysLog.getOperatingcontent());        return object;    }    /**     * 方法异常时调用     *     * @param ex     */    public void afterThrowing(Exception ex) {        System.out.println("afterThrowing");        System.out.println(ex);    }    /**     * 获取方法中的中文备注     *     * @param joinPoint     * @return     * @throws Exception     */    public static String getMthodRemark(ProceedingJoinPoint joinPoint) throws Exception {        String targetName = joinPoint.getTarget().getClass().getName();        String methodName = joinPoint.getSignature().getName();        Object[] arguments = joinPoint.getArgs();        Class targetClass = Class.forName(targetName);        Method[] method = targetClass.getMethods();        String methode = "";        for (Method m : method) {            if (m.getName().equals(methodName)) {                Class[] tmpCs = m.getParameterTypes();                if (tmpCs.length == arguments.length) {                    MethodLog methodCache = m.getAnnotation(MethodLog.class);                    if (methodCache != null) {                        methode = methodCache.remark();                    }                    break;                }            }        }        return methode;    }    /**     * 获取请求ip     *     * @param request     * @return     */    public static String getIp(HttpServletRequest request) {        String ip = request.getHeader("X-Forwarded-For");        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {            int index = ip.indexOf(",");            if (index != -1) {                return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip.substring(0, index);            } else {                return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;            }        }        ip = request.getHeader("X-Real-IP");        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {            return ip;        }        return request.getRemoteAddr().equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;    }}

  (3)新建日志实体【Syslog】

package org.triber.portal.service.logAop;import lombok.Getter;import lombok.Setter;import java.io.Serializable;/** * 操作日志实体类 */public class Syslog implements Serializable{    @Setter@Getter private String optId;    @Setter@Getter private String loginId;    @Setter@Getter private String loginName;    @Setter@Getter private String ipAddress;    @Setter@Getter private String methodName;    @Setter@Getter private String methodRemark;    @Setter@Getter private String operatingcontent;    @Setter@Getter private String optDate;    //模糊条件    @Setter@Getter private String serchCondition;}

  (4)日志切入【添加注解标志即可】

/**     * 删除金融机构     * @param request     * @param response     * @param operateVersionId 机构版本     * @param orgId 机构iD     * @param orgLvl 机构层级     * @return     * @throws Exception     */    @RequestMapping(value = "delOrgByFlagAndOrgId", method = RequestMethod.POST, produces = {"application/json"})    @MethodLog(remark = "删除机构")    public String delOrgByFlagAndOrgId(HttpServletRequest request,                                     HttpServletResponse response,                                     @RequestParam(value = "operateVersionId", required = false) String operateVersionId,                                     @RequestParam(value = "orgId", required = false) String orgId,                                     @RequestParam(value = "orgLvl", required = false) String orgLvl) throws Exception{        orgService.delOrgByFlagAndOrgId(areaIdPrefix,orgId, orgLvl, operateVersionId);        return "0";    }

  (5)maven注入aop依赖

org.springframework.boot
spring-boot-starter-aop
在application.properties文件里加这样一条配置spring.aop.auto=true在springboot项目里加这两条配置即可,就可以开启aop功能

总结:

  至此,大功告成,可以开始加注解标志,获取参数,记录关键信息,输出日志了。。。

  

 

转载于:https://www.cnblogs.com/hackxiyu/p/8072314.html

你可能感兴趣的文章
我的友情链接
查看>>
一双皮鞋
查看>>
oracle闪回操作详解
查看>>
复制仓库
查看>>
percent之Timer
查看>>
折腾Java设计模式之中介者模式
查看>>
腾讯电脑管家提醒您:该网站可能存在安全风险,请谨慎访问!怎么去除?
查看>>
tomcat下的内存设置,以及设置tomcat内存参数的查看
查看>>
django搭建博客网站
查看>>
《linux Shell 脚本攻略》进阶学习(第一部分)
查看>>
java 邮件收发
查看>>
我的友情链接
查看>>
struts2结合poi-3.7实现excel文件数据导入
查看>>
opessl工具使用
查看>>
自建CA以及证书申请
查看>>
Meta标签整理
查看>>
Apache prefork模式和worker模式参数详解
查看>>
rpm、yum和源码安装
查看>>
LAMP环境搭建
查看>>
oracle转mysql过程中的sum over处理
查看>>