Servlet 是 Server Applet 的缩写,译为“服务器端小程序”,是一种使用 Java 语言来开发动态网站的技术。Servlet 虽然被称作“小程序”,但是它的功能却异常强大,因为它是基于 Java 的,几乎可以使用所有的 Java API,Java 能做的事情,Servlet 也能做。
Java 是一种功能强大的通用型编程语言,可以处理 HTTP 请求,可以访问数据库,可以生成 HTML 代码,您完全可以使用原生 Java 来开发动态网站。但是,使用原生 Java 开发动态网站非常麻烦,需要自己解析 HTTP 请求的报头,需要自己分析用户的请求参数,需要自己加载数据库组件……种种原因导致使用原生 Java 开发动态网站几乎是一件不能被接受的事情。正是基于这种原因,Java 官方后来推出了 Servlet 技术,它对开发动态网站需要使用的原生 Java API 进行了封装,形成了一套新的 API,称为 Servlet API。
使用 Servlet 开发动态网站非常方便,程序员只需要集中精力处理业务逻辑,不需要再为那些基础性的、通用性的功能编写代码,这使得 Servlet 在动态网站开发领域具备了很高的实用性。
Servlet 基于 Java,可以使用几乎全部的 Java API,所以它的功能异常强大,完全可以胜任企业级开发,能够处理那些高并发、大吞吐量、业务逻辑复杂的应用场景。
您可以这样理解,Servlet 是 Sun 公司推出的一种基于 Java 的动态网站开发技术。编写 Servlet 代码需要遵循 Java 语法,一个 Servlet 程序其实就是一个按照 Servlet 规范编写的 Java 类。Servlet 程序需要先编译成字节码文件(.class文件),然后再部署到服务器运行。
Servlet 是第一代 Java Web 开发技术,用它开发非常麻烦,所以 Java 官方又推出了第二代 Web 开发技术JSP,JSP 才是现代化的 Web 开发技术,这里不多说(以上内容参考ref1)。
简而言之,servlet可以理解服务器端处理数据的java小程序。
我们编写的 Servlet 类没有 main() 函数,不能独立运行,那我们如何启动一个servlet,如何结束一个servlet,如何寻找一个servlet? 这一切都受控于另一个java应用,这个应用我们就称之为Servlet容器。servlet容器帮助我们管理着servlet等,使我们只需要将重心专注于业务逻辑。
在介绍Servlet容器之前,我们需要介绍下相关历史。
Web 服务器是一种对外提供 Web 服务的软件,它可以接收浏览器的 HTTP 请求,并将处理结果返回给浏览器。部署网站一般需要 Web 服务器的支持,例如:
运行 PHP 网站一般选择 Apache 或者 Nginx;
运行 ASP/ASP.NET 网站一般选择 IIS;
运行 Python 网站一般选择内置的 WSGI 服务器模块——wsgiref。
我们通常所说的 Web 服务器,比如 Apache、Nginx、IIS 等,它们的功能往往都比较单一,只能提供 http(s) 服务,让用户访问静态资源(HTML 文档、图片、CSS 文件、JavaScript 文件等),它们不能执行任何编程语言,也不能访问数据库,更不能让用户注册和登录。也就是说,如果只有 Web 服务器,那您只能部署静态网站,不能部署动态网站。
而随着互联网的发展,交互越发得重要,单纯的静态文件满足不了需求。业务变得复杂,需要我们编写代码来处理诸多业务。需要根据 HTTP 请求调用不同的业务逻辑来响应,那就需要部署动态网站。
要想部署动态网站,必须要有编程语言运行环境(运行时,Runtime)的和数据库管理系统的支持。即部署动态网站一般至少需要三个组件,分别是 Web 服务器、运行时和数据库。例如,部署 PHP 网站一般选择「Apache + PHP 运行时 + MySQL」的组合:
运行环境(运行时):
开发网站使用的编程语言一般都是脚本语言(比如 PHP、ASP、Python),部署网站时都是将源代码直接扔到服务器上,然而源代码自己并不能运行,必须要有解释器的支持;当用户访问动态页面时,解释器负责分析、编译和执行源代码,然后得到处理结果。解释器是执行脚本语言的核心部件,除此以外还有一些辅助性的部件,例如:
我们习惯将以上各种支持脚本语言运行的部件统称为运行环境,或者运行时(Runtime)。
数据库:
Web 服务器不带数据库,编程语言也不带数据库,数据库是一款独立的软件;要想实现用户注册、发布文章、提交评论等功能,就必须安装一款数据库,比如 MySQL、Oracle、SQL Server 等。
Servlet 是基于 Java 语言的,运行 Servlet 必然少不了 JRE 的支持,它负责解析和执行字节码文件(.class文件)。然而 JRE 只包含了 Java 虚拟机(JVM)、Java 核心类库和一些辅助性性文件,它并不支持 Servlet 规范。要想运行 Servlet 代码,还需要一种额外的部件,该部件必须支持 Servlet 规范,实现了 Servlet 接口和一些基础类,这种部件就是 Servlet 容器。
Servlet 容器就是 Servlet 代码的运行环境(运行时),它除了实现 Servlet 规范定义的各种接口和类,为 Servlet 的运行提供底层支持,还需要管理由用户编写的 Servlet 类,比如实例化类(创建对象)、调用方法、销毁类等。
一个动态页面对应一个 Servlet 类,开发一个动态页面就是编写一个 Servlet 类,当用户请求到达时,Servlet 容器会根据配置文件(web.xml)来决定调用哪个类。
Web 服务器是整个动态网站的“大门”,用户的 HTTP 请求首先到达 Web 服务器,Web 服务器判断该请求是静态资源还是动态资源:如果是静态资源就直接返回,此时相当于用户下载了一个服务器上的文件;如果是动态资源将无法处理,必须将该请求转发给 Servlet 容器。
Servlet 容器接收到请求以后,会根据配置文件(web.xml)找到对应的 Servlet 类,将它加载并实例化,然后调用其中的方法来处理用户请求;处理结束后,Servlet 容器将处理结果再转交给 Web 服务器,由 Web 服务器将处理结果进行封装,以 HTTP 响应的形式发送给最终的用户。
常用的 Web 容器有 Tomcat、Jboss、Jetty、WebLogic 等,其中 Tomcat 由 Java 官方提供,是初学者最常使用的。
为了简化部署流程,Web 容器往往也会自带 Web 服务器模块,提供基本的 HTTP 服务,因此这里的 Web容器 = Web服务器 + Servlet容器,所以您可以不用再安装 Apache、IIS、Nginx 等传统意义上的服务器,只需要安装一款 Web 容器,就能部署 Servlet 网站了。
正是由于这个原因,有的教材将 Tomcat 称为 Web 容器,有的教材又将 Tomcat 称为 Web 服务器;日常讨论时,也会将web容器称为servlet容器,两者的概念已经非常模糊了。
将 Web容器当做服务器使用后,上面的流程图就变成了下面的样子:
注意,Servlet 容器自带的 Web 服务器模块虽然没有传统的 Web 服务器强大,但是也足以应付大部分开发场景。
总结下来,Servlet 容器就是 Servlet 程序的运行环境,它主要包含以下几个功能:
servlet需要由servlet容器来管理,那么采取这种机制有什么好处呢?
利用容器提供的方法,你可以简单的实现servlet与web服务器的对话。否则你就要自己建立socket,监听端口,创建新的流等等一系列复杂的操作。而容器的存在就帮我们封装这一系列复杂的操作。使我们能够专注于servlet中的业务逻辑的实现。
web服务器监听来自特定端口(通常是80端口)的HTTP请求,当客户端(使用web浏览器的用户)发送一个HTTP请求时,Servlet容器会创建新的HttpServletRequest和HttpServletResponse对象,并且把它们传递给与请求URL匹配的Servlet实例的方法进行处理(所有的这些都使用同一个线程)。
request对象提供了获取HTTP请求的所有信息的入口,比如请求头和请求实体。response对象提供了控制和发送HTTP响应的便利方法,比如设置响应头和响应实体(通常是JSP生成的HTML内容)。当HTTP响应被提交并结束后,request和response对象都会被销毁。
容器负责servlet的整个生命周期。如何加载类,实例化和初始化servlet,调用servlet方法,并使servlet实例能够被垃圾回收。有了容器,我们就不用花精力去考虑这些资源管理垃圾回收之类的事情。
当Servlet容器启动时,它会部署并加载所有的web应用。当web应用被加载时,Servlet容器会一次性为每个应用创建Servlet上下文(ServletContext)并把它保存在内存里。Servlet容器会处理web应用的web.xml文件,并且一次性创建在web.xml里定义的Servlet、Filter和Listener,同样也会把它们保存在内存里。
当Servlet容器关闭时,它会卸载所有的web应用和ServletContext,所有的Servlet、Filter和Listner实例都会被销毁。
容器会自动为接收的每个servlet请求创建一个新的java线程,servlet运行完之后,容器会自动结束这个线程。
利用容器,可以使用xml部署描述文件来配置安全性,而不必将其硬编码到servlet中。
容器将jsp翻译成java!
step1: client点击一个URL,其URL指向一个servlet而不是静态界面
step2: 容器识别出这个请求索要的是一个servlet,所以创建两个对象:
<servlet>
<servlet-name>Ch1Servletservlet-name>
<servlet-class>ch1Servlet.Ch1Servletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>Ch1Servletservlet-name>
<url-pattern>/Ch1Servleturl-pattern>
servlet-mapping>
servlet有三个名字:
/Ch1Servlet
Ch1Servlet
ch1Servlet.Ch1Servlet
ref1. Servlet到底是什么
ref2. Servlet容器(Web容器)是什么
ref3. 为什么要有 Servlet ,什么是 Servlet 容器,什么是 Web 容器?
ref4. web开发中 web 容器的作用(如tomcat)
ref5. Web容器的作用