首页 > 代码库 > Servlet简单总结(一)

Servlet简单总结(一)

一、Servlet简单总结

1.1. 什么是Servlet

Servlet是JavaEE三大组建之一,是使用Java语言编写服务器端的程序,主要用来处理Web应用程序中的请求-响应。Servlet并没有main之类的执行方法,当用户访问服务器的时候,Tomcat是通过调用Servlet的某些方法来完成整个处理过程的。Servlet是运行在Tomcat服务器提供的Servlet容器中的,所以Servlet是不用程序指定调用的。

1.2. Tomcat与JavaEE

JavaEE的版本与Tomcat服务器的版本是存在一种对应关系的,在开发Web应用程序的时候,需要注意对应版本关系,不然可能引起Web程序报错。

JavaEE与Tomcat服务器的版本对应关系如下表:

Tomcat服务器版本

Servlet\JSP版本

JavaEE版本

Java运行环境

Tomcat 4.1

Servlet 2.3\JSP 1.2

JavaEE 1.3

JDK 1.3

Tomcat 5.0

Servlet 2.4\JSP 2.0

JavaEE 1.4

JDK 1.4

Tomcat 5.5\6.0

Servlet 2.5\JSP 2.1

JavaEE 5.0

JDK 5.0

Tomcat 7.0

Servlet 3.0\JSP 2.2

JavaEE 6.0

JDK 6.0

2. 编写一个Servlet

2.1. 通过Eclipse创建Servlet

开发工具Eclipse或MyEclipse本身提供了创建Servlet的功能,下面我们首先利用开发工具来创建一个Servlet,具体步骤如下:

  • 首先,我们创建一个Web工程。
  • Web工程的src目录下,鼠标右键点击“New”选项,选择“Servlet”选项。
  • 弹出创建Servlet的界面窗口,具体内容如下:
  • 输入Servlet的包名、名称及相关方法后,点击“Next”按钮进行下一步操作。

该界面是配置Servlet在web.xml文件中的相关信息,具体内容如下:

 Servlet/JSP Class Name:Servlet的完整路径。

 Servlet/JSP Name:Servlet的名称。

Servlet/JSP Mapping URL:配置Servlet拦截的路径,客户端通过该路径访问Servlet。

File Path of web.xml:当前工程的web.xml配置文件保存路径。

Display Name:显示名称。

Description:描述名称。

  • 配置完毕之后,点击“Finish”按钮,完成Servlet的创建工作。

创建完成之后,当前Web工程的变化是在src目录下多了一个Servlet的Java文件,在WEB-INF目录中的web.xml文件中多了Servlet相关配置信息。

将当前Web应用程序发布到Tomcat服务器,并启动Tomcat服务器运行测试当前创建的Servlet内容。

  • 通过Eclipse或MyEclipse将当前Web工程发布到Tomcat服务器,并启动Tomcat服务器。
  • 打开浏览器,在地址栏中输入http://localhost:8080/08_servlet/servlet/FirstServlet,访问服务器端的Servlet内容。

2.2. 手动编写一个Servlet

通过Eclipse或MyEclipse创建Servlet虽然简单,但我们并不知道相关代码是什么含义。所以,下面我们需要研究一下生成出来的代码。

首先, 我们来研究一下创建的Servlet文件源代码,会发现如下内容:

  • 是继承于HttpServlet类。
  • 包含init()、doGet()、doPost()和destroy()方法。

根据上述内容,我们可以手动创建一个Servlet的Java文件,如下面的代码所示:

 1 public class SecondServlet extends HttpServlet {
 2     @Override
 3     public void init() throws ServletException {
 4         System.out.println("这是init()方法...");
 5     }
 6     @Override
 7     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
 8             throws ServletException, IOException {
 9         System.out.println("这是doGet()方法...");
10     }
11     @Override
12     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
13         System.out.println("这是doPost()方法...");
14     }
15     @Override
16 public void destroy() {
17         System.out.println("这是destroy()方法...");
18     }
19 }

 

其次,我们再来研究一下web.xml配置文件增加的内容:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 7   <display-name></display-name>
 8   <servlet>
 9     <description>This is the description of my J2EE component</description>
10 <display-name>This is the display name of my J2EE component</display-name>
11 <!-- 
12         servlet标签:用于配置Servlet的名称和完整路径.
13          * servlet-name标签:用于为对应的Servlet设置名称.
14          * servlet-class标签:用于设置对应的Servlet的完整路径.
15    -->
16 
17     <servlet-name>FirstServlet</servlet-name>
18     <servlet-class>app.java.servlet.FirstServlet</servlet-class>
19   </servlet>
20 <!-- 
21         servlet-mapping标签:用于配置Servlet拦截客户端请求路径.
22          * servlet-name标签:用于设置对应使用的Servlet名称.
23          * url-pattern标签:用于设置客户端请求的拦截路径.
24            * 相对路径:/servlet/FirstServlet
25            * 绝对路径:http://localhost:8080/08_servlet/servlet/FirstServlet
26    -->
27 
28   <servlet-mapping>
29     <servlet-name>FirstServlet</servlet-name>
30     <url-pattern>/servlet/FirstServlet</url-pattern>
31   </servlet-mapping>
32   <welcome-file-list>
33     <welcome-file>index.jsp</welcome-file>
34   </welcome-file-list>
35 </web-app>

 

将当前Web应用程序发布到Tomcat服务器,并启动Tomcat服务器运行测试当前创建的Servlet内容。

  • 通过Eclipse或MyEclipse将当前Web工程发布到Tomcat服务器,并启动Tomcat服务器。
  • 打开浏览器,在地址栏中输入http://localhost:8080/08_servlet/servlet/SecondServlet,访问服务器端的Servlet内容。
  • 通过查看Eclipse或MyEclipse的console控制台的信息

2.3. Servlet的继承链

通过创建Servlet的Java文件中的代码内容,可以发现创建的Servlet是继承于HttpServlet类,查看JavaEE帮助文档中的HttpServlet内容。

Method Summary

protected  void

doGet(HttpServletRequest req, HttpServletResponse resp) 
          Called by the server (via the service method) to allow a servlet to handle a GET request.

protected  void

doPost(HttpServletRequest req, HttpServletResponse resp) 
          Called by the server (via the service method) to allow a servlet to handle a POST request.

protected  void

service(HttpServletRequest req, HttpServletResponse resp) 
          Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class.

 void

service(ServletRequest req, ServletResponse res) 
          Dispatches client requests to the protected service method.

通过帮助文档提供的内容,我们可以知道创建Servlet中的doGet和doPost方法是继承于HttpServlet提供的,但还有init和destroy方法没有找到。我们发现HttpServlet是继承于GenericServlet,查看JavaEE帮助文档中的GenericServlet内容。

Method Summary

 void

destroy() 
          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.

 void

init() 
          A convenience method which can be overridden so that there‘s no need to call super.init(config).

abstract  void

service(ServletRequest req, ServletResponse res) 
          Called by the servlet container to allow the servlet to respond to a request.

通过帮助文档提供的内容,我们可以知道init和destroy方法是源于GenericServlet。但是其实GenericServlet都实现了Servlet接口。

Method Summary

 void

destroy() 
          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.

 ServletConfig

getServletConfig() 
          Returns a ServletConfig object, which contains initialization and startup parameters for this servlet.

 String

getServletInfo() 
          Returns information about the servlet, such as author, version, and copyright.

 void

init(ServletConfig config) 
          Called by the servlet container to indicate to a servlet that the servlet is being placed into service.

 void

service(ServletRequest req, ServletResponse res) 
          Called by the servlet container to allow the servlet to respond to a request.

所以,init和destroy方法是Servlet接口提供的方法。通过上述的查找,我们已经很清晰的知道了Servlet的继承关系,具体如下图:

 

2.4. Servlet工作流程

利用Servlet完成的Web应用的实际工作流程是通过Tomcat服务器发布服务,客户端与服务器端之间的交互遵循Http协议完成的。具体工作流程如下:

  • 客户端浏览器向服务器端发送请求。
  • 服务器端由Tomcat服务器提供的Servlet容器解析接收到的请求。
  • 通过Web应用程序的配置文件web.xml,解析到对应执行的Servlet。
  • Servlet完成客户端发送的请求逻辑,并完成向客户端发送的响应内容。
  • Tomcat服务器提供的Servlet容器向客户端浏览器进行响应。

我们也可以通过下面的图来理解Servlet具体的工作流程。

 

技术分享

2.5servlet注意事项

值得注意的是Servlet内容是属于JavaEE内容,和使用JavaSE内容一样,都是需要引入JAR包的。使用Eclipse或MyEclipse创建Web应用程序的时候,会发现已经导入了JavaEE所需要的JAR包。其中javaee.jar包中包含了使用Servlet的所有内容。

但是,当把Web应用程序发布到Tomcat服务器的时候,发现对应的目录中并没有javaee.jar包。我们知道无论是编译还是运行都是需要这些JAR包的,这说明Tomcat服务器本身提供了Servlet运行所需要的环境。在Tomcat服务器的安装目录中的lib目录中可以找到servlet-api.jar包,该JAR包也提供了Servlet运行所需的环境。

我们如果想要手动编译Servlet的话,需要做以下及步:

  • Tomcat安装目录中的webapps目录创建Web工程名称及目录结构。
  • 在命令行中利用命令编译Servlet文件。

javac -classpath C:\Tools\apache-tomcat-7.0.55\lib\servlet-api.jar -d . Servlet.java

  • 在对应Web工程目录的WEB-INF目录中的web.xml进行配置。

3. 深入掌握Servlet

3.1. Servlet的生命周期

一般情况下,自定义Servlet都是继承HttpServlet。但通过HttpServlet的继承链,我们知道HttpServlet是实现了Servlet接口,下面列表是Servlet接口提供的所有方法。

Method Summary

 void

destroy() 
          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.

 ServletConfig

getServletConfig() 
          Returns a ServletConfig object, which contains initialization and startup parameters for this servlet.

 String

getServletInfo() 
          Returns information about the servlet, such as author, version, and copyright.

 void

init(ServletConfig config) 
          Called by the servlet container to indicate to a servlet that the servlet is being placed into service.

 void

service(ServletRequest req, ServletResponse res) 
          Called by the servlet container to allow the servlet to respond to a request.

上述所有方法中,init()、service()和destroy()方法叫做Servlet的生命周期。讨论一下有关生命周期的三个方法:

  • init()方法

Servlet实例化之后,Servlet容器会调用init()方法,主要是用来完成处理客户端请求之前的初始化工作。init()方法在Servlet的生命周期中只被执行一次。

  • service()方法

Servlet容器调用service()方法来处理客户端发送的请求。在service()方法被调用之前,必须保证init()方法被正确执行。service()方法在每次客户端发送请求之后,会被执行一次。

  • destroy()方法

 Servlet容器检测到当前Servlet实例被移除时,会调用destroy()方法,以便让Servlet实例可以释放所使用的所有资源。destroy()方法在Servlet的生命周期中也只被执行一次。

下面我通过实际操作来讨论关于Servlet的生命周期是怎么样的:

  • 首先,创建一个Servlet文件,具体如下。
 1 public class LifeServlet implements Servlet {
 2 
 3     public LifeServlet(){
 4         System.out.println("这里创建了一个Servlet实例对象...");
 5     }
 6 
 7     public void init(ServletConfig config) throws ServletException {
 8         System.out.println("这是init()方法...");
 9     }
10 
11     public void service(ServletRequest req, ServletResponse res)
12             throws ServletException, IOException {
13         System.out.println("这是service()方法...");
14     }
15 
16     public void destroy() {
17         System.out.println("这是destroy()方法...");
18     }
19     
20     public ServletConfig getServletConfig() {
21         return null;
22     }
23     public String getServletInfo() {
24         return null;
25     }
26 }
  • web.xml文件中,配置有关Servlet信息。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>LifeServlet</servlet-name>
    <servlet-class>app.java.servlet.LifeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LifeServlet</servlet-name>
    <url-pattern>/servlet/LifeServlet</url-pattern>
  </servlet-mapping>
</web-app>
  • Web应用程序发布到Tomcat服务器,并启动Tomcat服务器。
  • 启动Tomcat服务器之后,我们可以查看Tomcat服务器启动的日志内容,并没有有关Servlet信息。
五月 12, 2017 7:34:26 下午 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: E:\MyEclipse 2016 CI\binary\com.sun.java.jdk8.win32.x86_1.8.0.u66\bin;D:\tomcat\bin
五月 12, 2017 7:34:27 下午 org.apache.coyote.AbstractProtocolHandler init
信息: Initializing ProtocolHandler ["http-bio-8080"]
五月 12, 2017 7:34:27 下午 org.apache.coyote.AbstractProtocolHandler init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
五月 12, 2017 7:34:27 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 842 ms
五月 12, 2017 7:34:27 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
五月 12, 2017 7:34:27 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.11
五月 12, 2017 7:34:27 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory day11
五月 12, 2017 7:34:27 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory docs
五月 12, 2017 7:34:27 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory examples
五月 12, 2017 7:34:27 下午 org.apache.catalina.core.ApplicationContext log
信息: ContextListener: contextInitialized()
五月 12, 2017 7:34:27 下午 org.apache.catalina.core.ApplicationContext log
信息: SessionListener: contextInitialized()
五月 12, 2017 7:34:27 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory host-manager
五月 12, 2017 7:34:28 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory manager
五月 12, 2017 7:34:28 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory ROOT
五月 12, 2017 7:34:28 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory webmvcframework
五月 12, 2017 7:34:28 下午 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["http-bio-8080"]
五月 12, 2017 7:34:28 下午 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["ajp-bio-8009"]
五月 12, 2017 7:34:28 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 1061 ms
  • 打开浏览器,在地址栏中输入http://localhost:8080/08_servlet/servlet/LifeServlet,并查看控制台信息。

技术分享

  • 重新刷新页面,再次发送请求,调用Servlet内容

技术分享

  • 停止Tomcat服务器,并查看控制台信息。

通过上述操作,可以发现:在第一次向Servlet发送请求时,Tomcat服务器的Servlet容器首先创建Servlet实例对象,再进行Servlet初始化工作,最后调用service()方法来处理请求。第二次向Servlet发送请求时,只调用了service()方法,并没有执行Servlet的构造方法和init()方法。在停止Tomcat服务器时,Servlet的destroy()方法被调用,释放所使用的资源。

 

Servlet简单总结(一)