操作日志记录
1.存在的意义
所日志记录,就是记录所有的操作,使领导对这个系统的流转了如指掌,同时要是系统出现了问题,也可以清楚找到问题的所在。
2. 界面展示
3. 主要代码分析(提供三种方法)
3.1 方法一 使用aop实现
源码介绍:
01.首先在保证你的环境无误的情况下(我用的是ssh)
02.BussAnnotation.java (自定义注解)
package cn.bdqn.annotation; /** * 自定义注解(用于记录日志) */ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface BussAnnotation { // 模块名 String moduleName(); // 操作内容 String option(); }
03.LogBeforeAdvice.java (前置增强)---主要记录的方法
package cn.bdqn.aop; /** * aop前置增强结合自定义注解实现记录日志 */ import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.struts2.ServletActionContext; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.bdqn.annotation.BussAnnotation; import cn.bdqn.base.BaseService; import cn.bdqn.entity.PSUser; import cn.bdqn.entity.PsLogs; import cn.bdqn.service.IPsLogsService; public class LogBeforeAdvice implements MethodBeforeAdvice{ public void before(Method method, Object[] args, Object target) throws Throwable { // 拿到我们的service对象 ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); IPsLogsService bean = (IPsLogsService)context.getBean("pslsi"); //注解,拿到类型的元数据 BussAnnotation ol = method.getAnnotation(BussAnnotation.class); if (ol!=null) { System.out.println(ol.moduleName()+"\t"+ol.option()); //判断是否 PSUser user=(PSUser)ServletActionContext.getRequest().getSession().getAttribute("loginuserinfo"); PsLogs logs=new PsLogs(); if(user==null){//在登录的时候记录登录信息 String userCode = ServletActionContext.getRequest().getParameter("userCode");//登录界面的值 System.out.println(userCode); //赋值并保存 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(sdf.format(new Date())); logs.setOperateInfo(ol.option()); logs.setOperateDatetime(date); logs.setUserCode(userCode); ((BaseService<PsLogs>) bean).save(logs); }else{//登录后,直接记录我们自定义注解中指定的信息 //赋值并保存 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(sdf.format(new Date())); logs.setOperateInfo(ol.option()); logs.setOperateDatetime(date); logs.setUserCode(user.getUserCode()); ((BaseService<PsLogs>) bean).save(logs); } } } }
04.XXXAction.java (Action类中使用自定义注解实现记录)
/* * 用于登录 */ @BussAnnotation(moduleName="用户登录",option="登录") public String login() { //关键代码 return SUCCESS; }
05.applicationContext.xml (配置aop)
<!-- aop结合自定义注解实现日志记录 --> <bean name="logBefore" class="cn.bdqn.aop.LogBeforeAdvice"></bean> <aop:config proxy-target-class="true"> <aop:pointcut expression="execution(* *..action.*.*(..))" id="pointcut" /> <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut" /> </aop:config>
3.2 方法二 使用过滤器实现
源码介绍:
01.FunctionFilter.java (过滤器)---主要记录的方法
package cn.bdqn.filter; /** * 用于记录操作日志的过滤器类(方法二) */ import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** */ import cn.bdqn.entity.PSFunction; import cn.bdqn.entity.PSRole; import cn.bdqn.entity.PSUser; import cn.bdqn.entity.PsLogs; import cn.bdqn.service.IPsLogsService; public class FunctionFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("用于记录操作日志的过滤器类"); HttpServletRequest req=(HttpServletRequest)request; String url=req.getRequestURI(); System.out.println(url); //过滤掉所有静态资源,不做处理 if (url.endsWith(".js")) { chain.doFilter(request, response); } if (url.endsWith(".css")) { chain.doFilter(request, response); } if (url.endsWith(".html")) { chain.doFilter(request, response); } if (url.endsWith(".txt")) { chain.doFilter(request, response); } if (url.endsWith(".gif")) { chain.doFilter(request, response); } if (url.endsWith(".jpg") || url.endsWith(".jpeg")) { chain.doFilter(request, response); } if (url.endsWith(".png")) { chain.doFilter(request, response); } int pos=url.indexOf("?"); if (pos>-1) { url=url.substring(0,pos); } int actionindex=url.indexOf(".action"); if(actionindex>-1){ url=url.substring(0,actionindex); } int of = url.indexOf("/", 2); url=url.substring(of+1); System.out.println("url地址:"+url); //判断是否登录 PSUser user=(PSUser)req.getSession().getAttribute("loginuserinfo"); if(url.endsWith("login")||url.equals("")){ chain.doFilter(request, response); }else if(user!=null){ for (PSRole role : user.getRole()) { for (PSFunction function : role.getPsFunctions()) { if(function.getFuncUrl().equals(url)){ PsLogs log=new PsLogs(); log.setOperateDatetime(new Date()); log.setOperateInfo(function.getFunctionName()); log.setUserCode(user.getUserCode()); //获取spring的上下文容器 ApplicationContext contex=new ClassPathXmlApplicationContext("applicationContext.xml"); //获取spring容器中定义的IRoleService对象实例用于查询角色信息 IPsLogsService logsService = contex.getBean(IPsLogsService.class,"pslsi"); logsService.save(log); chain.doFilter(request, response); } } } }else{ HttpServletResponse resp=(HttpServletResponse) response; resp.setCharacterEncoding("utf-8"); resp.getWriter().write("<script type='text/javascript'>alert('您没有该权限')</script>"); } } public void init(FilterConfig arg0) throws ServletException { } }
02.web.xml
<!-- 配置记录日志的过滤器(方法二) --> <filter> <filter-name>functionfilter</filter-name> <filter-class>cn.filter.FunctionFilter</filter-class> </filter> <filter-mapping> <filter-name>functionfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3.3 方法三 使用拦截器实现
源码介绍:
01.BussAnnotation.java (自定义注解)
package cn.bdqn.annotation; /** * 自定义注解(用于记录日志) */ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface BussAnnotation { // 模块名 String moduleName(); // 操作内容 String option(); }
02.OperateLogIntercepter.java (自定义拦截器)---主要记录的方法
package cn.bdqn.interceptor; /** * 记录日志的拦截器(方法三) */ import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.bdqn.annotation.BussAnnotation; import cn.bdqn.base.BaseService; import cn.bdqn.entity.PSUser; import cn.bdqn.entity.PsLogs; import cn.bdqn.service.IPsLogsService; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class OperateLogIntercepter extends AbstractInterceptor{ private static final long serialVersionUID = 1L; private static final Log log=LogFactory.getLog(OperateLogIntercepter.class); @Override public String intercept(ActionInvocation invocation) throws Exception { /*Object bean = SpringContextHelper.getBean("psLogsService");*/ System.out.println("日志拦截器已经开始启动"); //获得service实例 ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); IPsLogsService bean = (IPsLogsService)context.getBean("pslsi"); Class<? extends Object> actionClass=invocation.getAction().getClass(); String methodName=invocation.getProxy().getMethod(); //获取当前方法 Method currentMethod=actionClass.getMethod(methodName); boolean flag = currentMethod.isAnnotationPresent(BussAnnotation.class); if(flag){ BussAnnotation ol=currentMethod.getAnnotation(BussAnnotation.class); PsLogs logs=new PsLogs(); PSUser user=(PSUser)ServletActionContext.getRequest().getSession().getAttribute("loginuserinfo"); if(user==null){//在登录的时候记录登录信息 String userCode = ServletActionContext.getRequest().getParameter("userCode"); System.out.println(userCode); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(sdf.format(new Date())); logs.setOperateInfo(ol.option()); logs.setOperateDatetime(date); logs.setUserCode(userCode); ((BaseService<PsLogs>) bean).save(logs); }else{//登录后,直接记录我们自定义注解中指定的信息 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(sdf.format(new Date())); logs.setOperateInfo(ol.option()); logs.setOperateDatetime(date); logs.setUserCode(user.getUserCode()); ((BaseService<PsLogs>) bean).save(logs); } } return invocation.invoke(); } public static Log getLog() { return log; } }
03.XXXAction.java (Action类中使用自定义注解实现记录)
/* * 用于登录 */ @BussAnnotation(moduleName="用户登录",option="登录") public String login() throws Exception { //主要代码 return SUCCESS; }
04.struts.xml (使用拦截器)
<!-- 拦截器 --> <interceptors> <!-- 声明记录日志拦截器 --> <interceptor name="logs" class="cn.interceptor.OperateLogIntercepter"></interceptor> <!-- 配置一个拦截器栈 --> <interceptor-stack name="myStack"> <!-- <interceptor-ref name="logs"></interceptor-ref> --> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!--默认使用这个拦截器栈 --> <default-interceptor-ref name="myStack"></default-interceptor-ref>