通过本教程,我将尝试使您更接近Java Servlet模型。 在检查servlet规范中定义的类之前,我将解释在开始开发Web应用程序之前需要了解的基本知识。
了解Java Servlet模型
首先,不仅为基于请求和响应编程模型的规范的Web应用程序定义Java Servlet模型。 但基本上,它最常用于与HTTP协议交互,因此从现在开始,我们将不再在HTTP应用程序中使用servlet模型。
基本上,Web应用程序应该是放置在Web上某个位置的应用程序,并且可以通过网络对其进行访问。 如果您需要更多信息并更好地定义“什么是Web应用程序”,则可以访问下一个链接: Web应用程序 。
如果我们要创建一个Web应用程序,我们应该有一个Web服务器,它可以是任何带有包含Web容器的HTTP服务器,例如Tomcat。 HTTP服务器负责处理客户端请求,安全性,向客户端提供内容等服务,但是HTTP服务器无法动态创建对客户端的响应,他可以提供静态内容。 解决此问题的方法是Web容器。 容器能够托管Web应用程序,HTTP服务器会将请求传递到将处理请求的Web容器。 通常,每台服务器只有一个容器。 服务器上的所有Web应用程序都由此容器提供服务。
Web容器内部的所有通信都是通过Web容器接口实现的。 这意味着一个应用程序不能直接访问另一个应用程序。 同样,一个应用程序内部的组件不能直接相互访问,同一应用程序中组件之间的所有通信都是使用Web容器接口实现的。 这对于理解Web应用程序在Web容器中的工作方式非常重要,它允许创建过滤器,侦听器,并允许使用Web容器的安全性功能。
战争应用结构
按照规范,Java Web应用程序打包在war程序包中。
War包与jar包相同,但是当Web容器在deploy文件夹中找到war文件时,它将假定它是一个Web应用程序并尝试启动它。
在war软件包中,我们有一个特殊的目录,称为WEB-INF。
此文件夹的内容不直接提供给用户。 该文件夹包含文件夹类和lib,我们可以在其中放置应用程序使用的类(类文件夹)和其他jar(lib文件夹)。 这些文件夹的内容将由类加载器自动读取,而无需对类路径进行任何其他设置。 此文件夹还包含web.xml文件,称为部署描述。 如果Web应用程序仅包含jsp页面,则不需要此文件,但是如果应用程序需要servlet或过滤器,则必须定义此文件。
Servlet生命周期
在servlet存在的过程中,它经历了五个生命周期:
- 装货
- 实例化
- 初始化
- 服务
- 破坏
加载是类加载器加载类的阶段。 每个Web应用程序都会获得一个不同的类加载器实例,这些实例将用于加载Web组件。 这允许在同一个容器中部署同一应用程序的两个版本,并且每个应用程序都可以具有相同名称的类(完整类名)。
加载后,Web容器将尝试实例化类(即创建类的新实例)。 通常每个Web组件仅创建一次,但这取决于Web容器的行为,在某些情况下,可以将Web容器设置为在池中创建更多的组件类实例,并使用池中的一个实例来服务请求。 当Web容器创建servlet的新实例时,它将使用默认构造函数。
初始化是生命周期阶段,在该阶段初始化servlet。 在此阶段中,应该让Servlet读取一些值并执行一些其他操作和步骤,然后Servlet才能满足客户请求。 服务阶段是servlet生命周期,其中servlet服务于客户端请求。 销毁阶段是Servlet生命的最后一个阶段,发生在将Servlet从服务中删除时。
Servlet接口
如果我们想创建一个servlet,那么应该做的就是实现Servlet接口。
该接口提供接下来的三种方法,这些方法由容器调用:
- init(ServletConfig config),在初始化期间调用
- 服务(ServletRequest请求,ServletResponse响应),在服务请求期间调用
- 当服务从服务中删除servlet时调用destroy()。
另外这个接口提供了两个辅助
方法:
- ServletConfig getServletConfig()
- 字符串getServletInfo()
在初始化期间,可以获取ServletException。 在init方法中引发此异常将通知容器发生了一些错误,并且容器将停止初始化并将Servlet实例标记为可用于垃圾回收器,并且这不会导致调用destroy方法。
同样在服务方法期间,可能会获取ServletException或UnavailableException。 此例外可以是临时的,也可以是永久的。 在临时异常的情况下,服务器将阻止对服务方法的调用一段时间,但是在永久异常的情况下,将调用destroy方法,并且Servlet将准备进行垃圾回收,并且以后对该Servlet的每次调用都将导致404响应。
GenericServlet类
GenericServlet类是javax.servlet包的一部分。 它是实现Servlet接口并创建不依赖平台的基本实现的抽象类。
此类介绍一种新方法:
- 在初始化阶段,由init(ServletConfig config)方法调用的init()
- ServletContext getServletContext(),提供对ServletContex的访问
- String getInitParameter(String name),检索在应用程序描述符中为指定名称定义的servlet配置参数的值
- 枚举getInitParameterNames(),返回所有servlet初始化参数的枚举。
- 字符串getServletName(),返回Servlet的名称。
如果我们扩展GenericServlet类而不是实现Servlet接口,那么我们要做的只是实现服务方法,所有其他方法都已经由抽象类实现了。
HttpServlet类
这也是类似于GenericServlet的抽象类,但此类与平台无关。 它与HTML协议绑定,并引入了仅与HTTP协议有关的新方法。 每个新方法都负责处理特定HTTP方法的客户端请求。
doXxx方法:
- doGet(HttpServletRequest请求,HttpServletResponse响应),处理获取请求
- doPost(HttpServletRequest请求,HttpServletResponse响应),处理发布请求
- doOptions(HttpServletRequest请求,HttpServletResponse响应),处理HTTP选项请求
- doPut(HttpServletRequest请求,HttpServletResponse响应),处理HTTP放置请求
- doDelete(HttpServletRequest请求,HttpServletResponse响应),处理HTTP删除请求
- doHead(HttpServletRequest请求,HttpServletResponse响应),处理HTTP Head请求
- doTrace(HttpServletRequest请求,HttpServletResponse响应),处理HTTP跟踪请求。
ServletContext接口
ServletContext接口是API,可用于访问有关应用程序的信息。 每个应用程序都是在自己的上下文中执行的,因此此接口可提供对该信息的访问。 该接口的实现由服务器供应商提供,我们对具体实现不感兴趣。 部署应用程序时,容器将首先创建ServletContext实现类,并用应用程序描述符提供的数据填充它。
我们可以将此接口内的方法分为几组:
- 访问上下文属性的方法:
- Object getAttribute(String name),从上下文中检索对象
- 枚举getAttributeNames(),检索属性名称
- void removeAttribute(String name),从上下文中删除属性
- setAttribute(String name,Object value),将新对象添加到上下文中并通过指定的名称绑定它。 如果具有指定名称的对象已经存在,它将被重载。
- 获取上下文信息的方法:
- 字符串getServletContextName(),检索由<display-name>在应用程序描述符中定义的值,如果不存在则返回null。
- String getRealPath(String path),指定资源的上下文相关路径,如果将应用程序部署为WAR(如果未在文件夹中爆炸),则为null。
- 设置getResourcesPaths(String path),在指定的部分路径内检索文件,仅一级
- ServletContext getContext(String appURL),检索部署在同一服务器上的另一个应用程序的ServletContex。 网址必须以“ /”开头
- 访问静态资源的方法:
- URL getResource(String path),获取由path指定的资源的URL。 路径必须以“ /”开头
- InputStream getResourceAsStream(String path),检索指定资源的InputStream。 路径可以是上下文相关的。
- String getMimeType(String path),返回资源的mie类型。
- 获取请求分配器的方法:
- RequestDispatcher getRequestDispatcher(String path),为指定资源返回RequestDispatcher,如果资源不存在,则返回null。
- RequestDispatcher getNamedDispatcher(String name),为部署描述符内的命名资源返回RequestDispatcher。
- 访问上下文初始化参数的方法:
- String getInitParameter(String name),检索部署描述符中定义的指定参数的值;如果不存在,则返回null。
- 枚举getInitParameterNames(),在应用程序部署描述符中定义的参数名称列表。
上下文属性是应用程序范围的属性,这意味着所有客户端共享相同的属性,一个客户端所做的属性更改对其他所有客户端都是可见的。
ServletConfig接口
这是API,提供用于访问在部署描述符中定义的信息的方法。 具体
对象由servlet容器创建,并在初始化阶段提供给servlet。 该接口定义了以下方法:
- String getInitParameter(String name),获取为具有指定名称的servlet定义的init参数的值;如果没有这样的参数,则为null。
- 枚举getInitParameterNames(),检索servlet初始参数名称的枚举。
- ServletContext getServletContext(),检索Servlet上下文。
- 字符串getServletName(),检索在web.xml中指定的servlet名称
如您所见,ServletConfig仅提供用于读取init参数的方法,而没有用于更改或添加新init参数的方法,因为它们无法更改或添加。
Servlet部署说明
如果要使用servlet,则需要在部署描述符中定义它们。
<servlet>
<description>This is a servlet</description>
<display-name>First Servlet</display-name>
<servlet-name>FirstServlet</servlet-name>
<class>ba.codecentric.scwcd.FirstServlet</class>
<init-param>
<param-name>firstParam</param-name>
<param-value>value</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<uri-pattern>/FirstServlet</uti-pattern>
</servlet-mapping>
在servlet标签内部,我们定义了servlet,在servlet标签内部,我们可以使用init param标签定义初始化参数,这些参数将在初始化阶段作为ServletConfig对象的一部分发送给servlet。
并使用servlet映射标记定义uri模式,该模式将用于激活指定的servlet。
同样在本教程中,我谈到了ServletContext,并且提到了上下文参数。 这些参数也使用上下文参数标签在部署描述中定义。
<context-param>
<param-name>contextParameter</param-name>
<param-value>value</param-value>
</context-param>
参考:来自ICG Madjeric博客的JCG合作伙伴 Igor Madjeric的有关Servlet的基础知识 。
翻译自: https://www.javacodegeeks.com/2012/11/basics-about-servlets.html