Listener执行流程

每次说起监听器,总是有些空的感觉,那么它到底是个什么东西呢?

一.概念

    监听器也叫 Listener,是 Servlet的监听器,它可以监听客户端的请求,服务端的操作等。

    监听器可以自动激发一些操作,比如监听在线的用户的数量. 当增加一个 HttpSession时,就激发 sessionCreated(HttpSessionEvent se) 方法,这样就可以给在线人数加 1。

 

二.执行原理

    其实监听器的执行类似于触发器,当某些动作(接口中定义好的)执行时就会触发(至于到底是如何触发的就是底层的问题了)相应的Listener,执行相应的操作;当然如果没有执行对应的动作,则监听器就一直监听着,没有操作。

    下面我来举个例子(监听在线用户的数量),来展示一下Listener的执行过程,先来看一下它的时序图:

    

    login.jsp

 

<%@ page language="java" contentType="text/html; charset=GB18030"
	pageEncoding="GB18030"%>
<%
	String command = request.getParameter("command");
	if ("login".equals(command)) {
		if ("dan".equals(request.getParameter("userId"))
				&& "123".equals(request.getParameter("password"))) {

			//登陆成功将用户信息放到session中
			session.setAttribute("user_name",
					request.getParameter("userId"));

			//设置超时,单位:秒
			session.setMaxInactiveInterval(6000);
			

			//重定向到主控页面
			response.sendRedirect(request.getContextPath() + "/index.jsp");
		}
	}
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>登录</title>
<SCRIPT language=JavaScript>
	function init() {
		loginForm.userId.focus();
	}

</SCRIPT>
</head>
<body οnlοad=init()>
	<FORM name="loginForm">
		<input type="hidden" name="command" value="login">	
		用户名:  
		<INPUT name="userId" value="dan" type="text" size="20"	maxlength="20"> 
		<p>密   码: 
		<INPUT name="password"	value="123" type="password" size="21" maxlength="20"> 
		<input type="submit" οnclick="submitForm()" value="提交" name="login" id="login">
	</FORM>
</body>
</html>


 

    TestHttpSessionListener.java

 

package listener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class TestHttpSessionListener implements HttpSessionListener {

	@Override
	public void sessionCreated(HttpSessionEvent se) {
		System.out.println("-------------TestHttpSessionListener.sessionCreated---------------------");
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {
		
	}

}


    TestHttpSessionAttributeListener.java

  

package listener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;


public class TestHttpSessionAttributeListener implements
		HttpSessionAttributeListener {

	@Override
	public void attributeAdded(HttpSessionBindingEvent se) {
		System.out.println("name==========" + se.getName());
		System.out.println("value==========" + se.getValue());
		if ("user_name".equals(se.getName())) {
			Integer count = (Integer)se.getSession().getServletContext().getAttribute("count");
			if (count == null) {
				count = 1;
			}else {
				count++;
			}
			se.getSession().getServletContext().setAttribute("count", count);
		}
		System.out.println("count=" + se.getSession().getServletContext().getAttribute("count"));
	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent se) {
		System.out.println("TestHttpSessionAttributeListener===>>>>>attributeRemoved" + se.getSession().getServletContext().getAttribute("count"));
	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent arg0) {
		System.out.println("TestHttpSessionAttributeListener===>>>>>attributeReplaced");
	}

}


    代码写完后,还需要在Web.xml中进行一下配置:

   

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
  
  <listener>
  	<listener-class>listener.TestHttpSessionListener</listener-class>
  </listener>
  
  <listener>
  	<listener-class>listener.TestHttpSessionAttributeListener</listener-class> 
 </listener>

</web-app>


     执行结果:

    代码解析:

     1.实现接口

     本例是实现了两个监听,一个是对Session的监听(可以没有),一个是对SessionAttribute的监听,在这里将两者都写出来,是让大家对这两者进行一下区分(明白Session和SessionAttribute是分开进行监听的)。

     既然是分开的,所以要实现不同的接口,至于为什么一定要实现接口,就是因为Web服务器对不同的接口已经进行了不同的封装,所以当你进行不同的操作时才会调用到不同的监听器上。

     2.attributeAdded(HttpSessionBindingEvent se)

     HttpSessionAttributeListener接口中的每一个方法中都有一个HttpSessionBindingEvent参数,它是一个事件对象,就是因为对于Session的Attribute的操作触发了该事件,所以才能将对session的attribute的操作触发到响应的方法来。

   

三.常用监听器

   前面只是提到了两种监听器,大家知道不同的操作对应不同的监听器,下面我就来为大家介绍一些常用的监听器:

    1.ServletContextAttributeListener:监听对 ServletContext 属性的操作,比如 增加,删除,修改属性.

    2.ServletContextListener监听 ServletContext.

       当创建 ServletContext 时,激 发 contextInitialized(ServletContextEventsce)方法;当销毁 ServletContext 时,激发 contextDestroyed(ServletContextEvent sce)方 法.       

    3.HttpSessionListener监听 HttpSession 的操作.

       当创建一个 Session 时,激发 session Created(HttpSessionEvent se)方法;当销毁一个Session 时,激 发 sessionDestroyed (HttpSessionEvent se)方法.

    4.HttpSessionAttributeListener 监听 HttpSession 中的属性的操作.

        当在 Session 增加一个属性时,激发 attributeAdded(HttpSessionBindingEvent se)方法;当在 Session 删除 一个属性时,激发 attributeRemoved(HttpSessionBindingEvent se)方法; 当在Session 属性被重新设置时,激发 attributeReplaced(HttpSessionBindingEvent se) 方法.

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Activiti 7 是一个基于 Spring Boot 和 Spring Cloud 的工作流引擎,其执行流程的代码比较复杂,需要涉及到多个模块和类。下面是 Activiti 7 执行流程的主要代码: 1. 创建流程实例 ```java BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); Process process = bpmnModel.getProcesses().get(0); FlowElement startElement = process.getFlowElements().stream() .filter(e -> e instanceof StartEvent) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No start event found in process definition " + processDefinitionId)); ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables); ``` 2. 执行用户任务 ```java Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); if (task != null) { taskService.complete(task.getId(), variables); } ``` 3. 完成流程实例 ```java ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); if (processInstance != null) { runtimeService.deleteProcessInstance(processInstanceId, reason); } ``` 4. 监听流程事件 ```java @EventListener public void onProcessStarted(ProcessStartedEvent event) { String processInstanceId = event.getProcessInstanceId(); // 处理流程启动事件 } @EventListener public void onTaskCreated(TaskCreatedEvent event) { String taskId = event.getTaskId(); // 处理任务创建事件 } @EventListener public void onTaskCompleted(TaskCompletedEvent event) { String taskId = event.getTaskId(); // 处理任务完成事件 } @EventListener public void onProcessCompleted(ProcessCompletedEvent event) { String processInstanceId = event.getProcessInstanceId(); // 处理流程完成事件 } ``` 以上是 Activiti 7 执行流程的主要代码,详细的实现可以参考 Activiti 7 的源码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值