文章是对 JSR-000340 JavaTM Servlet 3.1 Final Release的Java Servlet规范的翻译,尚未校准
应用事件设施为Web应用开发者提供了对 ServletContext
和 HttpSession
以及 ServletRequest
生命周期的更好的控制,允许更好的代码因子,并提高管理Web应用所使用资源的效率。
应用程序事件监听器是实现一个或多个Servlet事件监听器接口的类。在部署Web应用程序时,它们被实例化并在Web容器中注册。它们是由WAR中的开发者提供的。
Servlet事件监听器支持对 ServletContext
、HttpSession
和 ServletRequest
对象的状态变化进行事件通知。Servlet上下文监听器被用来管理资源或应用程序在JVM层面上的状态。HTTP会话监听器用于管理与同一客户或用户向Web应用程序发出的一系列请求相关的状态或资源。Servlet请求监听器用于管理Servlet请求的整个生命周期的状态。异步监听器用于管理异步事件,如超时和异步处理的完成。
可能有多个监听器类来监听每个事件类型,开发者可以指定容器为每个事件类型调用监听器Bean的顺序。
事件类型和用于监测它们的监听器接口显示在以下表格中。
TABLE 11-1 Servlet Context Events
Event Type | Description | Listener Interface |
---|---|---|
Lifecycle | 上下文刚刚被创建,可以为其第一个请求提供服务,或者Servlet上下文即将被关闭。 | javax.servlet.ServletContextListener |
Changes to attributes | 在servlet上下文上的属性已被添加、删除或替换。 | javax.servlet.ServletContextAttributeListener |
TABLE 11-2 HTTP Session Events
Event Type | Description | Listener Interface |
---|---|---|
Lifecycle | 一个HttpSession已经被创建、失效或超时。 | javax.servlet.http.HttpSessionListener |
Changes to attributes | 在一个HttpSession上,属性被添加、删除或替换。 | javax.servlet.httpHttpSessionAttributeListener |
Changes to id | HttpSession的id已经被改变。 | javax.servlet.httpHttpSessionIdListener |
Session migration | HttpSession已经被激活或钝化。 | javax.servlet.httpHttpSessionActivationListener |
Object binding | 对象已被绑定到HttpSession或从HttpSession解绑。 | javax.servlet.httpHttpSessionBindingListener |
TABLE 11-3 Servlet Request Events
Event Type | Description | Listener Interface |
---|---|---|
Lifecycle | 一个servlet请求已经开始被Web组件处理。 | javax.servlet.ServletRequestListener |
Changes to attributes | 在ServletRequest上添加、删除或替换了属性。 | javax.servlet.ServletRequestAttributeListener |
Async events | 超时、连接终止或异步处理的完成。 | javax.servlet.AsyncListener |
For details of the API, refer to the API reference.
为了说明事件的使用方案,考虑一个简单的Web应用程序,其中包含一些使用数据库的Servlet。开发者提供了一个用于管理数据库连接的servlet上下文监听器类。
Web应用程序的开发者提供了监听器类,实现了javax.servlet
API中的一个或多个监听器接口。每个监听器类必须有一个公共构造函数,不需要任何参数。监听器类被打包到WAR中,可以在WEB-INF/classes
归档条目下,也可以在WEB-INF/lib
目录下的JAR中。
监听器类在Web应用程序部署描述符中使用listener
元素进行声明。它们按类的名称列出,并按其被调用的顺序排列。与其他监听器不同,AsyncListener
类型的监听器只能以编程方式注册(使用ServletRequest
)。
Web 容器为每个监听器类创建一个实例,并在处理应用程序的第一个请求之前将其注册为事件通知。Web容器根据它们实现的接口和它们在部署描述符中出现的顺序来注册监听器实例。在Web应用执行过程中,给定事件的监听器大多按照它们的注册顺序被调用,但也有一些例外。例如,HttpSessionListener.destory
是以相反的顺序调用的。详见第8.2.3节,“从web.xml、web-fragment.xml和注解中组装描述符”。
在应用程序关闭时,监听器将按照与它们的声明相反的顺序被通知,对会话监听器的通知在对上下文监听器的通知之前。会话监听器必须在上下文监听器收到应用程序关闭的通知之前被通知会话无效的情况。
下面的例子是注册两个Servlet上下文生命周期监听器和一个HttpSession
监听器的部署语法。
假设com.acme.MyConnectionManager
和com.acme.MyLoggingModule
都实现了javax.servlet.ServletContextListener
,并且com.acme.MyLoggingModule
额外实现了javax.servlet.http.HttpSessionListener
。另外,开发者希望com.acme.MyConnectionManager
在com.acme.MyLoggingModule
之前得到servlet上下文生命周期事件的通知。下面是这个应用程序的部署描述符。
<web-app>
<display-name>MyListeningApplication</display-name>
<listener>
<listener-class>com.acme.MyConnectionManager</listenerclass>
</listener>
<listener>
<listener-class>com.acme.MyLoggingModule</listener-class>
</listener>
<servlet>
<display-name>RegistrationServlet</display-name>
...etc
</servlet>
</web-app>
容器需要在开始执行进入应用程序的第一个请求之前,完成Web应用程序中的监听器类的实例化。容器必须保持对每个监听器实例的引用,直到Web应用程序的最后一个请求得到服务。
ServletContext
和HttpSession
对象的属性变化可能同时发生。容器不需要将产生的通知同步到属性监听器类。维护状态的监听器类对数据的完整性负责,应该明确地处理这种情况。
监听器内的应用程序代码可能会在操作过程中抛出一个异常。一些监听器的通知发生在应用程序中另一个组件的调用树下。这方面的一个例子是设置会话属性的 servlet,其中会话监听器会抛出一个未处理的异常。容器必须允许未处理的异常由第 10.9 节 "错误处理 "中描述的错误页机制来处理。如果没有为这些异常指定错误页,那么容器必须确保以状态 500 发送一个响应。在这种情况下,该事件下没有更多的监听器被调用。
有些异常不会发生在应用程序中另一个组件的调用栈下。这方面的一个例子是,SessionListener
收到会话超时的通知并抛出一个未处理的异常,或者 ServletContextListener
在通知Servlet上下文初始化时抛出一个未处理的异常,或者 ServletRequestListener
在通知初始化或销毁请求对象时抛出一个未处理的异常。在这种情况下,开发者没有机会来处理这个异常。容器可能会用HTTP状态代码500来响应所有对Web应用程序的后续请求,以表示应用程序错误。
开发人员希望在监听器产生异常后进行正常的处理,必须在通知方法中处理他们自己的异常。
在分布式Web容器中,HttpSession
实例的范围是服务会话请求的特定JVM,而ServletContext
对象的范围是Web容器的JVM。分布式容器不需要将servlet context事件或HttpSession
事件传播给其他JVM。监听器类实例的范围是每个JVM的部署描述符声明一个。
监听器类为开发者提供了一种在Web应用程序中跟踪会话的方法。在跟踪会话时,了解会话是否因为容器超时而变得无效,还是因为应用程序中的Web组件调用了 invalidate
方法,通常是很有用的。可以使用监听器和 HttpSession
API方法间接地确定这种区别。
文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99
文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效
文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是
文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件
文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件
文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码
文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware
文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停
文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待
文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析
文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code
文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象