关于Servlet和异步Servlet

Servlet API是Java EE标准的一部分,自1998年正式发布2.1规范以来,一直是基于Java的企业体系结构的重要组成部分。

它是一种自以为是的API,用于服务围绕一些基本概念构建的请求/响应协议:

  • 兼容的容器 ,这是一个专用的运行时,可以是独立服务器(过去更常见),也可以是基于库的嵌入式运行时(如今更常见)。 它可以支持一次托管多个Web应用程序,并在它们之间隔离类加载。 它还可以提供管理功能,例如应用程序部署,启动,停止,资源分配,JNDI命名上下文,带有连接池的JDBC数据源,HTTP适配器,线程池等。 它基本上是Java EE功能的集中管理软件包,可以删除兼容的应用程序。
  • 一个或多个servlet ,即实现Servlet接口的类,它不是特定于HTTP的,因为Servlet规范通常是为请求/响应协议设计的。 实现接口意味着处理大多数容器已经处理过的servlet配置信息,因此扩展作为规范一部分的抽象类(如GenericServlet甚至HttpServlet )更为普遍(方便)。 除了生命周期管理外,其余要实现的方法是请求处理程序 ,当请求进入时,容器将调用该请求处理程序 ,并应为它们提供服务。 他们将通过处理从容器本身作为参数接收的可变请求和响应对象(也包括标准接口)来实现此目的,或者通过在发生某些意外情况时引发异常来进行处理,容器将根据配置方式对其进行适当的管理,例如,通过重定向到JSP页面。 它们还可以包括处理并将处理(的一部分)委托给一个全新的处理链,该处理链通过RequestDispatcher映射到一些不同的URL。 这是作为链接servlet的一种机制,主要在2.3引入过滤器之前使用。
  • 一个或多个过滤器 ,扩展了Filter接口,并且与servlet类似,不同之处在于它们支持链接 ,即它们按顺序排列,可以将请求处理(的一部分)委托给链中的下一个过滤器,并执行发布-处理完成时。 Servlet始终位于过滤器链的末尾。
  • 设置信息 ,例如请求和过滤器到HTTP请求的映射,可以通过多种方式提供,从XML描述符到类注释再到实际的初始化代码。
  • 请求服务线程 :每个请求由一个专用线程服务,该线程将运行该请求本身已映射到的整个筛选器链,并阻塞与HTTP请求和响应相关的网络I / O操作以及任何其他线程完成请求处理所需的-blocking调用。

剖析Servlet API

如果我们试图表征长期存在的Servlet API,则可以将其限定为:

  • 绝对涉及对象,因为涉及的每个概念(无论多么抽象)都已被对象化并转换为接口或类。 “ Servlet”,“ Filter”,“ RequestDispatcher”都是这种建模风格的示例。 唯一的例外是容器本身,它是幕后的无处不在的参与者,但没有唯一的表示形式,可以通过显式参与者或诸如上下文之类的次要对象进行间接处理。
  • 它是基于(面向对象)模式的 ,我们可以识别其中的许多 模式
  • 它具有状态机语义 ,它是有状态的 ,并且是可变的,因为假设请求处理过程处于某种状态(这是所有API的对象化参与者的状态的总和,包括容器),那么会有一些操作将其转换为一种新的,可部分检查的不同状态,同时禁止其他转换(例如,在提交响应后转发请求)。
  • 它是基于处理程序的,因为您(开发人员)在感觉舒适时不会请求传入的请求,而是将它们推送到您的servlet上,您不得不将它们编码为目标化的请求处理程序。
  • 它是低级的,因为它不提供路由机制,也没有建立特定的范例,例如MVC。
  • 它最初是同步产生的,因为处理程序应该在调用计算上下文(堆栈)内完成请求处理,而根本不打算延迟请求。
  • 它明确地基于线程,因为规范指出处理程序的计算上下文是servlet容器线程。 同步和基于线程的结合在一起基本上意味着Servlet API最初被设计为线程阻塞的

总而言之,它是一个非常复杂且自以为是的API,尽管它基于非常普遍的观点并且具有很长的向后兼容历史。

顺便说一句:Clojure的戒指,HTTP服务器的全新明晰和简约视图

尽管Clojure社区非常多元化,并且在每个领域都有很多非常有趣的选择,但事实上的Clojure低级,基本的网络标准框架是Ring 。

鉴于HTTP几乎是一个无状态的请求-响应协议,HTTP请求服务自然是一个非常适合于功能性,输入-输出建模风格的领域。 实际上,Ring认为HTTP请求总共具有3个具有直接关系的功能实体:

  • 处理程序是一个函数,它接收唯一具有众所周知的键名和值类型的Clojure映射作为输入,表示HTTP请求,并生成另一个Clojure映射作为其输出,该Clojure映射必须具有表示HTTP响应的特定结构(这是不过,这过于简化了,因为Ring允许返回更简单的数据结构以方便使用)。
  • 中间件是一个接收处理程序功能并生成另一个处理程序功能的功能。 因此,中间件是一种高阶函数,旨在以某种特定方式丰富任何处理程序的逻辑,例如拦截和处理文件系统请求或使用多部分预处理信息来丰富请求本身,因此类似于Servlet过滤器,尽管通过一流的函数之类的函数式编程思想使其变得更加简单。 请注意,可以通过功能组合的直接方式将中间件按特定顺序链接 ,因为将中间件应用于处理程序所获得的是另一个处理程序,然后可以将多个中间件功能应用于该处理程序。
  • 适配器是一个函数,它接收处理程序函数作为其主要输入,并且不返回任何内容。 它的目的纯粹是产生一些HTTP服务器的副作用,该HTTP服务器将使用提供的处理程序来处理请求,因此实际上是某些先前存在的(或新的)HTTP服务器技术的适配器。 它的功能接口不是标准的,因为它可以接收的输入在很大程度上取决于技术,但是一个常见的模式是许多适配器将处理程序作为第一个参数来接收,然后将与实现相关的选项映射(或其他序列)作为第一个参数。第二个。 此外,最常用的选项(例如侦听接口和端口)在大多数适配器中往往具有相同的键名。

Ring也是一种自以为是的API,并且在某些方面它并不偏离流行的概念,例如,它仍然是基于处理程序的,尽管适配器只是功能的想法使得将其用作嵌入式HTTP非常简单。完全传统应用程序的边界”; 加上它是同步的, 这非常好,因为它使代码简单易维护。 仍然需要对主题保持一种新鲜,清晰和简约的观点,尝试完全消除偶发的复杂性,并提供最少数量的正交概念,以利用功能编程思想和动态语言灵活性来简洁有效地处理领域的内在复杂性。为了这个 这种方法非常符合Clojure语言本身的精神。

请注意,Ring对执行上下文一无所知:对于某人而言,基于轻量级光纤而不是重量级线程来为其阻塞API实现适配器是完全可以的:这正是Comsat提供的,Ring的清晰和极简性极大地简化了此类编写整合。

Servlet 3.0异步

Servlet规范的Async附加示例说明了以下事实:OOP不一定简化有状态API的复杂性。 有时相反,它只能通过在表中散布状态,将其拆分并放入对象中来提供这样做的危险幻觉。

这种错觉实际上会使情况变得更糟,因为它使我们认为,开发有状态API的看似非常简单的想法确实可以在没有意外后果的情况下工作。

Servlet 3.0中 Async功能背后的“简单”思想是一种新的请求模式,即异步请求模式 。 当通过startAsync方法调用将请求切换为异步时,我们“简单地”告诉容器,只要请求处理链(过滤器和Servlet)返回并且其关联的容器线程完成,我们就根本不意味着请求处理已经完成,因此不应将响应发送回HTTP客户端。 相反,应将其保留,直到其他执行上下文发出确实已完成请求处理的信号为止,并且它将通过对startAsync调用返回的AsyncContext对象的completedispatch方法调用来complete

不用说,异步模式与先前存在的Servlet API的有状态移动部分可能存在几种交互作用:接下来,我们将对其中的一些进行交互。

异步模式下的错误处理

AsyncContext提供了注册有关请求处理进度和异常情况的侦听器的功能,但是我们将在容器线程之外运行自管理执行上下文,因此容器无法为我们捕获和处理异常。

相反, AsyncContext确实提供了一种新的处理委托形式,它将控制权转移回容器管理的线程,这就是dispatch方法的目的。 通过在请求属性中设置错误条件(和任何其他相关信息)之后使用它,并检查请求的调度程序类型,我们可以验证我们确实在处理源自异步处理流程的异常条件,然后选择重新引发异常,这一次可以依靠容器的管理能力。

这种方法有点复杂,并且基本上需要使用经过改进的前向/调度功能,事实上,这些功能实际上已被过滤器弃用。 但是它可以工作,并且能够模仿在同步设置中发生的错误处理流程。 衡量它的效率当然很有趣。

Servlet API也一直提供sendError功能,但到目前为止, 尚不清楚它是否(以及如何)以异步模式工作,即使在大多数流行的servlet容器(如Jetty和Tomcat)中,这种情况也很容易导致开放问题 。

在异步模式下过滤

Servlet 3.0规范明确禁止在与容器线程不同的执行上下文中运行过滤器链接。 此限制意味着,在请求处理链末尾的唯一处理程序(即Servlet)可以将请求置于异步模式,而预处理过滤器逻辑只能在容器的线程中执行。

这是非常不幸的,因为自从引入过滤器以来,许多流行的框架和应用程序开发人员就使用了过滤器来执行大量的请求处理,而这些请求处理可以受益于在单独的执行上下文(例如光纤)中运行而不会阻塞昂贵的容器线程。

实际上,在流行的servlet容器中有一些关于此限制的未解决问题 。

Servlet 3.1:异步HTTP I / O

Servlet 3.0可以从请求处理完成中分离容器的线程和Servlet的处理代码,但是用于读取请求和写入响应的I / O仍然是线程阻塞的。

Servlet 3.1通过setReadListenersetWriteListener方法向请求添加了异步I / O功能 (如果它们已处于异步模式)。

这套新的API有一些缺点:

  • 最多可以注册一个读和一个写侦听器。
  • 将请求置于异步模式 ,API才会强制注册它们。
  • 侦听器接口是全新的,例如,与NIO API没有任何共同点。
  • 异步API允许更有效的实现,但是这样做的方式是错误的 ,即采用卷积编程模型,而不是提供比线程更有效的执行上下文,同时保持极其有用的“阻塞”抽象。 另一方面, 异步API可以很容易地转换为高效和富于表现力的光纤阻塞 API 。

“现状”和前进的方向

许多具有实质性结构的组织已经在基于Servlet的技术上投入了大量资金,因此改变方向是一项相关的成本,需要权衡具体的好处。

他们中的一些人对此感到满意,并且不受现有缺点的影响。 至于其他的可能性,并希望将来会发生,将来的servlet规范将解决这些问题,但是servlet API是一个庞大而复杂的规范。 它还需要保持一定程度的向后兼容性,因此发布规范审查可能要花费一些时间,更不用说servlet容器正确,有效和可靠地实现它们了。

当然,可以使用诸如Ring之类的servlet替代方案,并且某些组织可以决定使用它们来支付API的费用,以提高生产力并允许构建更多可维护的代码资产。 对于新的实现而言,此成本通常会更低,而不是移植现有的实现。

如果您的组织中基于servlet的API最明显的缺点是效率或异步编程模型的缺点,那么Comsat中存在一种非常可行且成本低廉的替代方案:它将使您仍然可以使用简单的阻塞抽象和熟悉的抽象Servlet API(以及Web和DB领域中的许多其他流行的和标准的API),但具有光纤提供的效率水平。

翻译自: https://www.javacodegeeks.com/2015/04/on-servlets-and-async-servlets.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux c++ 运行时报 段错误 的一个原因

很长时间没有写 c/c了 这次依据一些代码写了一个linux上的小东西,结果在运行时用new 创建对象的时候,报: 段错误 有可能还出现如下报错信息: *** glibc detected *** ./selectServer: malloc(): memory corruption: 0x0000000000fba740 *** 研究了一会儿…

mysql主键和聚簇索引_[MySQL] innoDB引擎的主键与聚簇索引

mysql的innodb引擎本身存储的形式就必须是聚簇索引的形式 , 在磁盘上树状存储的 , 但是不一定是根据主键聚簇的 , 有三种情形:1. 有主键的情况下 , 主键就是聚簇索引2. 没有主键的情况下 , 第一个非空null的唯一索引就是聚簇索引3. 如果上面都没有 , 那么就是有一个隐藏的row-i…

JPA数据库架构生成

一段时间以来, JPA的大多数主要实现,例如Hibernate , EclipseLink或OpenJPA ,都提供了生成数据库模式对象的方法。 这些包括表,主键,外键,索引和其他对象的生成。 不幸的是,当处理多…

ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调

近期项目中可能要用到Flash存取数据,并与JS互调,所以就看了一下ActionScript 3.0,现把学习结果分享一下,希望对新手有帮助。 目录 ActionScript 3.0简介 Hello World 文件读写 数据存储(SharedObject) 与JS互调 ActionScript 3.0简…

阿里云服务器mysql默认密码_阿里云服务器修改MySQL初始密码---Linux学习笔记

主要方法就是修改 MySQL按照文件下面的my.cnf文件首先是找到my.cnf文件,# find / -name “my.cnf”# cd /etc接下来最好是先备份my.cnf文件,对于初手而言#/etc vi my.cnf之后找到[mysqld]的段,在那段中插入一行:skip-grant-tables…

Quasar和Akka –比较

actor模型是用于容错和高度可扩展系统的设计模式。 角色是独立的工作程序模块,仅通过消息传递与其他角色进行通信,可以与其他角色隔离而失败,但是可以监视其他角色的故障并在发生这种情况时采取一些恢复措施。 参与者是简单,孤立但…

dlgdata.cpp错误提示 解决方案

1、在测试编写继承CStatic类组件时候,发现在调用调试过程中弹出一个错误,点忽略还可以继续运行。如下图: 2、dlgdata.cpp此文件是VS安装目录\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc中的文件,而出现此错误一般是所…

mysql主从复制时间配置_MySQL主从复制配置

环境CentOS 7.5Docker 1.13.1MySQL 8.0.16基于以上环境启动三个mysql容器,一个为master,二个为slavemaster和slave使用的mysql版本是完全一致的,未测试不同版本的mysql配置master编辑配置文件编辑master的配置文件my.cnf$ vim /usr/mysql/con…

告别异步代码

Quasar是一个向JVM添加真正的轻量级线程(纤维)的库。 它们非常便宜且非常快-实际上,光纤的行为就像Erlang进程或Go goroutines-并允许您编写简单的阻塞代码,同时享受与复杂异步代码相同的性能优势。 在本文中,我们将学…

如何利用多核CPU来加速你的Linux命令

如何利用多核CPU来加速你的Linux命令 原文出处: rankfocus 译文出处: 外刊IT评论 你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作——一些无法并行的操作。数据专家们,我是在对你们说…

魔术二传手反模式

设置者和获取者是邪恶的。 创建JavaBean定义时,这似乎是个好主意。 但是它们对Java社区造成了很大的伤害。 通常不如null指针那么多,但足够了。 首先,许多初级人员认为实现setter和getter(嘿,在Eclispe中只需单击几下…

sqlwarning mysql_mysql提示[Warning] Invalid (old?) table or database name问题的解决方法

DROP TABLE IF EXISTS [TEMP_TABLE_NAME];create temporary table [TEMP_TABLE_NAME] select col1,col2,... from [TABLE_NAME];alter table [TEMP_TABLE_NAME] add unique idx_col1(col1);经过以上操作中,多次出现该warning问题。通过查询和跟踪调试源码&#xff0…

C语言操作符优先级

转自:http://www.cnblogs.com/xiehy/archive/2010/02/04/1663825.html 优先级 运算符 含 义 要求运算 对象的个数 结合方向 1 () [] -> . 圆括号 下标运算符 指向结构体成员运算符 结构体成员运算符 自左至右 2 ! 逻辑非运算符 1 (单目运算符)…

linux mysql select_MySQL-Select语句高级应用

阅读目录1.1 SELECT高级应用1.2 select中where子句使用1.3 select中ORDER BY子句1.4 LIMIT子句1.5 多表连接查询1.6 Informatica_schema获取元数据1.7 参考文献1.1 SELECT高级应用1.1.1 前期准备工作本次测试使用的是world数据库,由MySQL官方提供下载地址&#xff1…

为AWT的机器人创建DSL

Java SDK附带了java.awt.Robot类,该类允许键盘和鼠标输入的自动化以及屏幕捕获的创建。 如果您想编写一个模拟用户输入的小型测试应用程序,或者只想自动化一些重复文本的输入,则此功能非常有用。 但是您不想每次都编写一个完整的Java应用程序…

Win7下硬盘安装Redhat双系统

Win7下硬盘安装Redhat Linux 形成双系统过程详解 需要软件 EasyBCD2.0 和 linux ISO 系统镜像 RedHat linux下载地址:http://www.linuxidc.com/Linux/2013-01/78017.htm 安装前准备工作: 1 一个 Windows 盘 D E F 任选其一都可以,将其格式化为FAT32 格式…

java rmi漏洞工具_学生会私房菜【20200924】Weblogic WLS核心组件反序列化命令执行突破(CVE20182628)漏洞复现...

学生会私房菜学生会私房菜是通过学生会信箱收集同学们的来稿,挑选其中的优质文档,不定期进行文档推送的主题。本期文档内容为:Weblogic WLS核心组件反序列化命令执行突破(CVE-2018-2628)漏洞复现》作者介绍:ChowChow,一…

Java泛型中的多态

从作为Java程序员的早期开始,我们都知道如何实例化和使用Collection对象。 实例化为具体类的List接口将如下所示。 List myArrayList new ArrayList();如果myArrayList应该仅保存Integer对象,则从Java 5编译器开始,按照Java Generics规范…

ASP.NET伪静态-无法读取配置文件,因为它超过了最大文件大小的解决办法

一直都在使用微软URLRewriter,具体的使用方法我就不多说了,网上文章很多。 但最近遇到一个问题,就是当web.config文件里面设置伪静态规则过多,大于2M的时候,就报错:无法读取配置文件,因为它超过…

java定义list_我的Java Web之路59 - Java中的泛型

本系列文章旨在记录和总结自己在Java Web开发之路上的知识点、经验、问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人。目录介绍再谈Java中的类型为什么需要泛型?Java中的泛型泛型类型泛型方法总结介绍还记得我在这篇文章(我的Java Web之路3…