千家信息网

怎样创建一个与Servlet-api完全解耦和的管理员后台操作日志监控

发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,怎样创建一个与Servlet-api完全解耦和的管理员后台操作日志监控,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。在日
千家信息网最后更新 2024年11月28日怎样创建一个与Servlet-api完全解耦和的管理员后台操作日志监控

怎样创建一个与Servlet-api完全解耦和的管理员后台操作日志监控,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

在日常开发系统后台时,需要针对管理员操作进行监控,如果使用Spring这一套技术体系,使用AOP切面编程+自定义注解不妨是一个好办法,但是在使用这一套体系的同时也会出现一些坑。比如这一套体系是完全依赖于WEB环境,脱离WEB环境就会出现出现ServletRequestAttributes为null的情况。那么如何解决这个问题。

首先快速搭建一个Spring 的运行环境具体jar参照下图:

javax.servlet

servlet-api

2.5

provided


javax.servlet

jstl

1.2


org.springframework

spring-core

4.3.2.RELEASE

org.springframework

spring-context

4.3.2.RELEASE

org.springframework

spring-context-support

4.3.2.RELEASE

org.springframework

spring-beans

4.3.2.RELEASE

org.springframework

spring-aop

4.3.2.RELEASE

org.springframework

spring-expression

4.3.2.RELEASE

org.springframework

spring-aspects

4.3.2.RELEASE

org.springframework

spring-tx

4.3.2.RELEASE

org.springframework

spring-web

4.3.2.RELEASE


org.springframework

spring-jdbc

4.3.2.RELEASE


org.springframework

spring-webmvc

4.3.2.RELEASE


org.mybatis

mybatis

3.2.5



org.mybatis

mybatis-spring

1.3.2


mysql

mysql-connector-java

5.1.38


com.alibaba

druid

1.1.10

com.alibaba

fastjson

1.2.47

commons-fileupload

commons-fileupload

1.3


com.fasterxml.jackson.core

jackson-databind

2.9.5


log4j

log4j

1.2.16

junit

junit

4.12

test


首先对前面的开发步骤做一个简单的讲解,首先开发一个自定义注解:

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 LogAnnotation {

public String value();

}

开发环绕通知(常规做法,下面做修改)

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;

import java.lang.reflect.Method;

import java.util.Date;

/*

*

* 这是一个环绕通知

* 需要实现

* */

public class Around implements MethodInterceptor {

@Override

public Object invoke(MethodInvocation mi) throws Throwable {

/*

* 1.什么人--------

* 2.什么时间 new Date()

* 3.什么事情----方法名

* 4.是否成功-----能

* */

ServletRequestAttributes s = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

//获取HttpRequst对象,于Servlet强耦合

HttpSession session = s.getRequest().getSession();

//拿到存放在Session的数据

String adminName = (String)session.getAttribute("admin");

//时间

Date date = new Date();

//什么事情

Method method = mi.getMethod();

//拿到类对象 反射

LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);

//通过反射拿到的实例 调用方法

String name = annotation.value();

//是否成功

boolean flag = false;

Object proceed = null;

try {

proceed = mi.proceed();

flag=true;

}catch (Exception a){

a.printStackTrace();

}

//这里不做插入数据库的操作

System.out.println(adminName+"管理员在"+date+"执行了"+name+"成功了么?"+flag);

return proceed;

}

}


上述实现的修改(于Servlet弱耦合),利用Spring的DI特性,实现对操作对象的自动注入。

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Method;

import java.util.Date;

/*

* 这是一个环绕通知

* 需要实现

* */

public class Around implements MethodInterceptor {

//将操作对象声明为成员变量

private String adminName;

//设置公开访问方法,实现未来的数据注入

public void setAdminName(String adminName) {

this.adminName = adminName;

}


@Override

public Object invoke(MethodInvocation mi) throws Throwable {

Date date = new Date();

//什么事情

Method method = mi.getMethod();

//拿到类对象 反射

LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);

//通过反射拿到的实例 调用方法

String name = annotation.value();

//是否成功

boolean flag = false;

Object proceed = null;

try {

proceed = mi.proceed();

flag=true;

}catch (Exception a){

a.printStackTrace();

}

System.out.println(adminName+"管理员在"+date+"执行了"+name+"成功了么?"+flag);

return proceed;

}

}

以上将操作数据设定为成员变量,未来我可以在controller层和业务层增加一个过滤器,实现对操作数据的注入。

3. 对通知类使用Spring进行管理

过滤器的开发

import com.baizhi.aop.Around;

import org.springframework.web.context.WebApplicationContext;

import org.springframework.web.context.support.WebApplicationContextUtils;


import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

import java.io.IOException;


public class LogFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {


}


@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

filterChain.doFilter(servletRequest, servletResponse);

HttpServletRequest res = (HttpServletRequest)servletRequest;

HttpSession session = res.getSession();

String admin = (String) session.getAttribute("admin");


ServletContext servletContext = session.getServletContext();

//使用这个web工具类拿到WebApplicationContext对象

WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);

//能通过WebApplicationContext类拿到已经初始化的Bean

Around around = (Around) webApplicationContext.getBean("around");

//通过set方法注入数据

around.setAdminName(admin);

}

@Override

public void destroy() {


}

}

5.最后在web.xml中进行配置

log

com.baizhi.filter.LogFilter

log

/*

搞定测试,这样做的好处是可以在测试某个模块时,只关注于String类型的name就行了,不必去考虑web的session的获取问题和null值问题

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

0