JAVA系列---Servlet详解

目录

  • 背景
    • 为何会出现Servlet
    • Web开发的本质
  • Servlets
    • CGI
    • FastCGI
    • WSGI
    • Servlet
    • 总结
  • wsgi与servlet
    • 出现时间
    • 社区特点
    • 对web开发的影响
  • servlet详解
    • 特性
    • 主要工作
    • 执行逻辑
  • 应用
    • Tomcat
      • 背景
      • embedded tomcat
      • 本质

背景

为何会出现Servlet

Servlet是Server Applet 的缩写,译为“服务器端小程序”,是一种使用 Java 语言来开发动态网站的技术。虽被称作“小程序”,但其功能却异常强大,因为它是基于 Java 的,所以几乎可以使用所有的 Java API,Java 能做的事情,Servlet 也能做。
Java 是一种功能强大的通用型编程语言,可以处理 HTTP 请求,可以访问数据库,可以生成 HTML 代码,您完全可以使用原生 Java 来开发动态网站。但是,使用原生 Java 开发动态网站非常麻烦,需要自己解析 HTTP 请求的报头,需要自己分析用户的请求参数,需要自己加载数据库组件……种种原因导致使用原生 Java 开发动态网站几乎是一件不能被接受的事情。正是基于这种原因,Java 官方后来推出了 Servlet 技术,它对开发动态网站需要使用的原生 Java API 进行了封装,形成了一套新的 API,称为 Servlet API。
Servlet之所以产生就是为了更方便的开发动态网站,程序员只需要集中精力处理业务逻辑,不需要再为那些基础性的、通用性的功能编写代码。

最终演变:Sun 公司推出一种基于 Java 的动态网站开发技术–Servlet。编写 Servlet 代码需要遵循 Java 语法,一个 Servlet 程序其实就是一个按照 Servlet 规范编写的 Java 类。Servlet 程序需要先编译成字节码文件(.class文件),然后再部署到服务器运行。它的功能异常强大,完全可以胜任企业级开发,能够处理那些高并发、大吞吐量、业务逻辑复杂的应用场景。

严格来说,Servlet其实只是一套 Java Web 开发的规范,或者说是一套 Java Web 开发的技术标准。只有规范并不能做任何事情,必须要有人去实现它。所谓实现 Servlet 规范,就是真正编写代码去实现 Servlet 规范提到的各种功能,包括类、方法、属性等。

Servlet 规范是开放的,除了 Sun 公司,其它公司也可以实现 Servlet 规范,目前常见的实现了 Servlet 规范的产品包括 Tomcat、Weblogic、Jetty、Jboss、WebSphere 等,它们都被称为“Servlet 容器”。Servlet 容器用来管理程序员编写的 Servlet 类。

Web开发的本质

也就是说,java是为了更方便的进行web开发才出现的servlet,所以搞清楚web开发的本质,就搞定了servlet的本质。

Web应用的本质:

  1. 浏览器发送一个HTTP请求;
  2. 服务器收到请求,生成一个HTML文档;
  3. 服务器把HTML文档作为HTTP响应的Body发送给浏览器;
  4. 浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。

所以,最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML返回。Apache、Nginx、Lighttpd等这些常见的静态服务器就是干这件事情的。

如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。

正确的做法是底层代码由专门的服务器软件实现,我们专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以需要一个统一的处理。

Servlets

任何语言都可以进行web开发,在Web部署的方案上,有一个方案是目前应用最广泛的:

  1. 首先,部署一个Web服务器专门用来处理HTTP协议层面相关的事情,比如如何在一个物理机上提供多个不同的Web服务(单IP多域名,单IP多端口等)这种事情。
  2. 然后,部署一个用各种语言编写(Java, PHP, Python,Ruby等)的应用程序,这个应用程序会从Web服务器上接收客户端的请求,处理完成后,再返回响应给Web服务器,最后由Web服务器返回给客户端。

那么,要采用这种方案,Web服务器和应用程序之间就要知道如何进行交互。为了定义Web服务器和应用程序之间的交互过程,就形成了很多不同的规范。这种规范里最早的一个是CGI][3,1993年开发的。后来又出现了很多这样的规范。比如改进CGI性能的FasgCGI,Java专用的Servlet规范,还有Python专用的WSGI规范等。提出这些规范的目的就是为了定义统一的标准,提升程序的可移植性。

CGI

CGI(Common Gateway Interface) 是WWW技术中最重要的技术之一,有着不可替代的重要地位。CGI是外部应用程序(CGI程序)与WEB服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的过程。

它允许Web浏览器发送请求到Web服务器,并将用户输入与服务器端执行的程序进行交互。通过CGI技术,可以实现动态生成网页、处理表单数据、访问数据库等功能。CGI程序是基于脚本语言编写的,常用的有Perl、Python、PHP等语言。

CGI程序包括两个主要部分:服务器端和客户端。服务器端负责解析客户端请求并调用相应的CGI程序进行处理,然后将处理结果返回给客户端。客户端则负责向Web服务器发送请求,并将请求结果呈现给用户。

在CGI程序中,服务器端通过标准输入和标准输出与客户端进行通信。当Web服务器收到一个CGI请求时,它会创建一个新的进程来执行该请求,并将输入数据作为标准输入传递给CGI程序。CGI程序处理完数据后,将结果通过标准输出返回给Web服务器。

CGI技术可以实现动态网页的生成和数据传输。当用户访问一个动态网页时,Web服务器接收到请求并将页面请求发送到CGI程序中。CGI程序读取页面请求并从数据库或其他数据源获取所需的信息,然后将这些信息插入到HTML模板中,最终生成动态网页并返回给Web服务器。Web服务器再将动态网页发送到用户端显示。

相比于静态网页,动态网页能够根据用户的不同请求生成不同的页面内容,因此具有更广泛的应用场景。例如,在电子商务领域中,动态网页可以根据用户的购买历史和偏好推荐相关商品,从而提高用户的购物体验和满意度。

虽然CGI技术在Web开发中具有广泛的应用前景,但是其也存在一些局限性和不足。首先,CGI程序往往需要消耗大量的系统资源,导致处理速度较慢,并且扩展性不够强。其次,由于CGI程序必须在每个请求中重新启动,因此会导致额外的性能损失。此外,CGI程序还存在一定的安全隐患和漏洞,需要采取相应的措施进行防范和修复。

随着Web技术的不断发展和进步,现代Web开发更倾向于使用其他技术,如ASP、JSP、Servlets等,这些技术可以更好地满足Web应用程序的需求,并具有更高的效率和安全性。与CGI相比,这些技术可以实现更高效的网页生成和数据传输,同时也能够更好地保护Web应用程序的安全性。

然而,尽管CGI技术存在一些局限性,但它在某些领域仍具有重要的应用价值。例如,在一些小型网站中,CGI技术可以提供简单有效的动态网页生成方法。此外,在一些特殊的环境中,如互联网浏览器兼容性测试等方面,CGI技术仍然具有不可替代的作用。

CGI的处理步骤:

  1. 通过Internet把用户请求送到web服务器。
  2. web服务器接收用户请求并交给CGI程序处理。
  3. CGI程序把处理结果传送给web服务器。
  4. web服务器把结果送回到用户。

FastCGI

FastCGI是一种网络协议,它是工作在socket上、而与语言无关的。以前的CGI一般来说是每个请求进来时,从server fork出一个进程,仅仅处理这一个请求,处理完成就退出,处理的过程是从环境变量中获取HTTP头,从标准输入中读取POST数据,从标准输出中输出HTTP响应。由于需要不停地创建和销毁进程,这种实现方式性能是比较低下的,功能也受到许多限制。FastCGI是CGI的一种改进,它在单个连接上接受连续的多个请求,一个一个进行处理,这样就提高了吞吐量。FastCGI和CGI一样与语言无关,任何语言只要遵循FastCGI的协议就可以使用FastCGI;但是它的处理模型是受限的,通常在单个连接上一次只能处理一个请求,这样要达到一定的并发度,就必须创建许多进程。

WSGI

WSGI的全称是Web Server Gateway Interface,翻译过来就是Web服务器网关接口。具体的来说,WSGI是一个规范,定义了Web服务器如何与Python应用程序进行交互,使得使用Python写的Web应用程序可以和Web服务器对接起来。

WSGI相当于是Web服务器和Python应用程序之间的桥梁。其目的只有两个:

  1. 让Web服务器知道如何调用Python应用程序,并且把用户的请求告诉应用程序。
  2. 让Python应用程序知道用户的具体请求是什么,以及如何返回结果给Web服务器。

Servlet

Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:

  1. Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第4步,否则,执行第2步。
  2. 装载并创建该Servlet的一个实例对象。
  3. 调用Servlet实例对象的init()方法。
  4. 创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
  5. WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

总结

CGI、WSGI、servlet 和类似的东西。其作用大同小异, 实质就是服务器运行脚本并发送其输出的一种方式,而不是一些静态网页。

Web 开发昨天还没有诞生,标准(和名称)还没有被某个神圣的实体透露。人们尝试了不同的方法来使相同(或类似)的东西工作,而通用网关接口(interface)一直是旨在标准化这些东西的规范。嗯,在 20 多年前的那个时代,互联网(和网络开发)主要是一项学术业务,学者们喜欢“大”名(嗯,营销人员更喜欢他们)。

至于 servlet,在 Java 世界中(总是有点具体),有 小程序 对于客户端(浏览器)端任务,因此服务器端任务的名称变为 小服务程序 .

对于一件未知的事情,你必须了解事物是如何演变的,而不仅仅是它们现在的样子。

wsgi与servlet

web开发的接口规范除了最早的cgi,各个语言也开始有自己独立的规范。

这些规范从产生的过程中看分为两类,一个弱势如wsgi,一个强势如servlet。

wsgi从外观上很接近cgi的调用方式,和unix环境中调用一个程序也很类似:给你一堆环境变量,加上参数。如果把wsgi application 看作一个脚本,其实就是外界通过wsgi 调用python的脚本而已。

从功能上servlet要比wsgi复杂得多。wsgi更多关注接口层,只要返回规定格式的数据,至于appliation中怎么实现并无要求。servlet规定了各个组件的写法,往往要继承某个基类,override某几个方法,然后在web.xml中配置,还有复杂的生命周期管理。

wsgi的规范就是 pep333 和 pep 3333,servlet3.0的规范是个230页的pdf。

二者只是在web开发中有对应的地位,但实现细节,操作细节都差别很大。

刚从java web开发接触python的时候对wsgi和servlet的差别简直不可想像,这也成为我一直很好奇的地方,现在总结有两个原因。

出现时间

关于wsgi 和servlet 有几个时间特别值得玩味,

python诞生于1989年,而pep333(第一个wsgi规范)是03年发布。

java诞生于 1995年,而servlet发布于1997年。

看过 《wsgi 之 因何而生》的读者应该了解 wsgi 规范因为要适应业已存在的诸多python web框架,必须做到简单,否则这些框架很难实现,pep333 就是一纸空文。

java语言诞生不久,加上当时web的流行,cgi编程方兴未艾,在java web框架还几乎没有的时候,java之父就开始构思完整的web开发规范,足见servlet的远见。以后几乎所有的java web框架都遵循统一的规范,这也是java web开发可以大规模推广的原因。想想python web开发者在选择框架时的傲娇。。。

社区特点

python 发迹于科研界,因为快速开发原型的特点被中小企业认可,后来得益于google的“推广”,得以进入众多开发者的视线。但是推动python发展的社区一直都是松散的,一直不温不火的发展着。在这样的环境中想强行去统一一件事,需要投入的资源是社区本身承受不了的。

java背后一直都是大公司,可以做到花钱保证高质量,走的是高端大气上档次的路线。生于大公司,用于大企业。java的世界里充满了一致和规范。

对web开发的影响

wsgi 对各个web 框架的影响太弱,熟悉wsgi对于你熟悉某个python web开发框架帮助并不大, 你还是需要看框架的文档。只要熟悉了servlet,如果不使用各serlvlet应用服务器特殊的功能,切换应用服务器其实学习成本并不高。在最终部署方式来说,无疑servlet更加适合开发,运维等角色分离的大公司做法。

和servlet 不同,python的web框架可以差异巨大,就像一个生物圈,什么物种都有,从老泰龙钟的zope到新潮的bottle。可选择的范围广,加上用python写个可用的web框架实在不难(基础工具一大堆),拼拼凑凑一个“框架”就出来了。 所以python的web开发技术上可以很快进化。

随着web开发技术的成熟,很多开发人员希望更多地控制web开发地细节,相比大一统地web框架,小巧灵活地web开发工具包更加受新一代developer的青睐。这也是web技术发展的一个方向。

如果崇尚自由可定制,可以尝试wsgi web开发的信马由韁,如果坚守稳定可靠, servlet的规范一致给你足够的信心。好坏只在你的需求,无关对错。

servlet详解

特性

// 重点方法
ServletRequestAttributes(服务应用程序请求属性)
ServletResponseAttributes(服务应用程序响应属性)

public interface Servlet + public interface ServletConfig 
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable ==》 general 不注册(通用)的应用程序
public abstract class HttpServlet extends GenericServlet  ==》 http协议的应用程序

public final class CGIServlet extends HttpServlet   ==Common Gateway Interface 公共网关接口应用程序

public class DefaultServlet extends HttpServlet 

public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware
  • Servlet(Server Applet)是 Java Servlet 的简称,称为小服务程序或服务连接器,用 Java 编写的服务器端程序,是运行在Web服务器或应用服务器上的程序,它是作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。Servlet具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

  • Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

  • 狭义的 Servlet 是指 Java 语言实现的一个接口,广义的 Servlet 是指任何实现了这个 Servlet 接口的类,一般情况下,人们将 Servlet 理解为后者。Servlet 运行于支持 Java 的应用服务器中。从原理上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP 协议的 Web 服务器。

  • 最早支持 Servlet 标准的是 JavaSoft 的 Java Web Server,此后,一些其它的基于 Java 的 Web 服务器开始支持标准的 Servlet。

  • 使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

  • Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:

    • 性能明显更好。
    • Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
    • Servlet 是独立于平台的,因为它们是用 Java 编写的。
    • 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
    • Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。
  • Java Servlet 是运行在带有支持 Java Servlet 规范的解释器的 web 服务器上的 Java 类。

  • Servlet 可以使用 javax.servlet 和 javax.servlet.http 包创建,它是 Java 企业版的标准组成部分,Java 企业版是支持大型开发项目的 Java 类库的扩展版本。这些类实现 Java Servlet 和 JSP 规范。

  • Java Servlet 就像任何其他的 Java 类一样已经被创建和编译。在安装 Servlet 包并把它们添加到计算机上的 Classpath 类路径中之后,就可以通过 JDK 的 Java 编译器或任何其他编译器来编译 Servlet。

  • Servlet 是 JavaEE 下的技术标准,不是 JDK 的组成部分,所以在编译 Servlet 前,需要先引入 servlet-api.jar 包(在 Apache Tomcat 安装目录下的 lib 文件夹中提供了此 jar 包)。

主要工作

浏览器请求静态内容:–》web服务器
浏览器请求动态内容:–》web服务器 --》 servlet容器 --》 servlet程序

因此常见链路:web browser-》 http protocol -》 http server -》 servlet -》 database

  • 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。

  • 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。

  • 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。

  • 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。

  • 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。

执行逻辑

  1. 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器
  2. 加载和实例化 Servlet。这项操作一般是动态执行的。然而,Server 通常会提供一个管理的选项,用于在 Server 启动时强制装载和初始化特定的 Servlet。
  3. init()
  4. service()
  5. destory()
  6. 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。

应用

Tomcat

背景

首先,Tomcat服务器是java开发语言开发的,是一个免费的开放源代码的Web应用服务器。是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现。

Jakarta,开放源代码开发项目,受到来自IBM等公司在财力和技术上的鼎力支持。是Apache基金旗下的开源Java项目社区,著名的Tomcat服务器即出自Jakarta旗下。为方便管理,剥离Tomcat、Lucene等大型、成熟的子项目,成为相对独立的Apache直接子项目。
Jakarta项目于2011年12月21日退役,无剩余子项目。

以上便是Tomcat的生长环境。

  • Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的Web 应用服务器
  • 实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当tomcat运行时,它实际上作为一个与Apache 独立的进程单独运行的
  • 当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet
  • Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器
  • 独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器
  • Tomcat最新版本为10.0.23

embedded tomcat

最近开发项目时才发现,原来tomcat有两种: org.apache.tomcat 和 org.apache.tomcat.embed

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starters</artifactId>
  <version>2.2.7.RELEASE</version>
</parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.7.RELEASE</version>
<name>Spring Boot Web Starter</name>
<description>Starter for building web, including RESTful, applications using Spring
MVC. Uses Tomcat as the default embedded container</description>
<url>https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-web</url>
<organization>
  <name>Pivotal Software, Inc.</name>
  <url>https://spring.io</url>
</organization>
  1. tomcat和embedded tomcat都是 Apache Tomcat官方发布的,从官网上看,从Tomcat 7开始, tomcat和embedded tomcat版本是同步发布的。
  2. 同时,也可以看到,独立版tomcat有window 32、64版本和unix版本,而embedded tomcat没有区分操作系统。
  3. 估计embedded tomcat代码和tomcat应该是一样的,可能做了一些精简,但具体减少了些什么东西,官方并没有说明,但有一点几乎可以确定:独立的tomcat有操作系统native支持和APR特性,但embedded没有这方面的支持。另外,在jmx和可监控性上,embedded tomcat是否支持,比如是否支持以MBean的形式监控embedded tomcat?另外,独立版tomcat支持SSI,我经常用到,embedded tomcat有这个功能,但没有说明文档,只能去翻源代码。
  4. 从官网每个版本的bugfix列表可以看到,和embedded相关的bug还比较多,embedded的使用上面还不是特别成熟,可能会遇到更多的问题。
  5. 有一点很重要,embedded tomcat几乎没有任何说明文档,网上资料也太少了,甚至找不到embedded tomcat的性能测试。更别说如果在embedded tomcat上做一些高级特性的配置,只能自己去摸索

总之,embedded tomcat尽量不要用

本质

  1. tomcat就是一个容器而已,一个软件,运行在java虚拟机。
  2. tomcat是一种能接收http协议的软件,因此其实java程序员自己也可以写出http解析的服务器。
  3. tomcat支持servlet,tomcat有自己写好的java jar包,java.servlet.*jar包,只需要编写相关程序时import 这个包就好。
  4. tomcat 的jar路径:package jakarta.servlet.http;

你可能感兴趣的:(java,servlet,开发语言)