Spring MVC 下Session监听器监听设置小细节

本文介绍了解决SpringMVC项目中Session监听器无法直接使用依赖注入的问题,并提供了一个具体的实现案例,展示了如何在监听器中手动获取所需的Bean。

今天在SpringMVC项目中加入了一个Session监听事件,当在web.xml中注册后启动项目一直报异常,之后查证后发现,原来session监听类中不能进行依赖注入,而我同时又必须要用注入方式进行实例化,最终经过多次试验,终于解决了问题,下面是具体代码:

//记得 到web.xml中注册监听
public class SessionListenerLog implements HttpSessionListener, ServletRequestListener{
	
	private HttpServletRequest request;

	//监听事件中 不能添加依赖注入
	//@Resource(name="AuditLogServiceImpl")
	private AuditLogService auditLogService;
	
	@Override
	public void sessionCreated(HttpSessionEvent event) {
		//当client端访问server端jsp页面时,session也就创建了
		//但并不意味着用户就已经登录,因此登陆日志不写在这
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent event) {
		//可将下面类中需要的类都进行依赖注入,非常方便
		ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext();
		auditLogService = (AuditLogService) ctx.getBean("AuditLogServiceImpl");
		
		//但退出日志写在这里
		//只要用户退出,理论上session需要被销毁
		HttpSession session = event.getSession();
		String LoginName = (String) session.getAttribute("sessionUserName");
		StringBuilder sb = new StringBuilder();
		
		//details 信息
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:dd:ss");
		sb.append("退出时间: ").append(sdf.format(new Date())).append("\n");
		sb.append("退出用户: ").append(LoginName).append("\n");
		String detailsMsg = sb.toString();
		
		if(detailsMsg.length() != 0 ){
			String GUID = new RandomGUID().toString().replaceAll("-", "");
			GUID = GUID.substring(1, GUID.length()-1);
			//记录日志基本信息
			ZfSysLogBasicBean logBasic = auditLogService.insertZfSysLogOutBasic(
					request, "AJ", "", "LOGOUT", "", "100335",
					SessionListenerLog.class, GUID,LoginName);
			auditLogService.insertZfSysLogDetails(detailsMsg, logBasic);
		}
	}
	
	@Override
	public void requestInitialized(ServletRequestEvent requestEvent) {
		request = (HttpServletRequest) requestEvent.getServletRequest();
	}
	@Override
	public void requestDestroyed(ServletRequestEvent requestEvent) {
		
	}
}



### Spring MVC监听器的使用及实现方法 #### 1. 监听器的作用 在Spring MVC框架中,监听器主要用于监控应用程序生命周期内的各种事件。这些事件可以是Web应用的启动和关闭、HTTP请求的创建和销毁以及Session的状态变化等[^2]。 #### 2. 常见的监听器及其功能 以下是几种常见的Spring MVC监听器及其主要用途: - **`ContextLoaderListener`**: 这是一个实现了`ServletContextListener`接口的类,用于加载Spring的应用上下文(ApplicationContext)。它会在Web容器启动时初始化Spring容器,并在容器关闭时释放资源[^1]。 - **`RequestContextListener`**: 实现了`ServletRequestListener`接口,专门用来处理HTTP请求级别的事件。每当有新的HTTP请求到达时,该监听器会被触发并绑定当前线程到对应的请求对象上。这使得开发者可以在控制器或其他组件中轻松获取与当前请求关联的信息。 - **自定义监听器**: 开发者可以根据业务需求编写自己的监听器来响应特定类型的事件。例如,可以通过实现`HttpSessionListener`接口来跟踪用户的Session状态变化,或者通过继承`ApplicationListener<T>`来捕获更复杂的领域模型事件[^3]。 #### 3. 配置监听器的方式 监听器可以通过两种方式进行配置——基于XML文件声明式配置或利用Java注解编程式注册。 ##### (1) XML方式配置 这是传统的做法,在web.xml文件里指定相应的listener标签即可完成设置工作。下面给出一个例子展示如何添加上述提到过的两个核心监听器实例: ```xml <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- RequestContextListener --> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> ``` ##### (2) 注解驱动模式下的自动装配机制 随着Spring版本迭代更新至较新阶段之后, 推荐采用更为简洁优雅的方式来管理bean life cycle management 及 event publishing process via annotations like @ComponentScan,@EnableAutoConfiguration etc., 同样也能达到相同效果. 比如对于某些场景下如果希望某个class成为application level listener,则只需简单标记如下所示annotation 即可生效: ```java @Component public class MyCustomEventListener implements ApplicationListener<MyEvent> { public void onApplicationEvent(MyEvent event){ System.out.println("Received custom event:"+event.getMessage()); } } ``` 此处需要注意的是此类必须被纳入component scanning path范围内才能正常运作. #### 4. 示例代码片段 以下提供了一个简单的示例演示如何创建并激活一个针对session超时期间的定制化处理器逻辑流程. ```java @WebListener public class SessionTimeoutMonitor implements HttpSessionAttributeListener { private static final Logger logger = LoggerFactory.getLogger(SessionTimeoutMonitor.class); @Override public void attributeAdded(HttpSessionBindingEvent se) {} @Override public void attributeRemoved(HttpSessionBindingEvent se) {} @Override public void attributeReplaced(HttpSessionBindingEvent se) { String name = se.getName(); Object value = se.getValue(); if ("user".equals(name)) { // Assuming 'user' is the key used to store user info in session logger.info("User object has been replaced due to timeout or manual invalidation."); ServletContext application = se.getSession().getServletContext(); Integer count = (Integer)application.getAttribute("inactiveUsersCount"); if(count==null){count=0;} application.setAttribute("inactiveUsersCount", ++count); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值