Servlet

Table of Contents

1 Java Servlets简介

Java Servlets are programs that run on a Web or Application server and act as a middle layer between a request coming from a Web browser or other HTTP client and databases or applications on the HTTP server.

Java Servlets often serve the same purpose as programs implemented using the Common Gateway Interface (CGI).

Servlets could in principle communicate over any client-server protocol, but they are most often used with the HTTP protocol. Thus "servlet" is often used as shorthand for "HTTP servlet".

参考:
Java™ Servlet Programming: https://docstore.mik.ua/orelly/java-ent/servlet/index.htm
The Java EE 6 Tutorial, Chapter 15 Java Servlet Technology: http://docs.oracle.com/javaee/6/tutorial/doc/bnafd.html

1.1 Servlet Tasks

Servlets perform the following major tasks:

  • Read the explicit data sent by the clients (browsers). This includes an HTML form on a Web page or it could also come from an applet or a custom HTTP client program.
  • Read the implicit HTTP request data sent by the clients (browsers). This includes cookies, media types and compression schemes the browser understands, and so forth.
  • Process the data and generate the results. This process may require talking to a database, executing an RMI or CORBA call, invoking a Web service, or computing the response directly.
  • Send the explicit data (i.e., the document) to the clients (browsers). This document can be sent in a variety of formats, including text (HTML or XML), binary (GIF images), Excel, etc.
  • Send the implicit HTTP response to the clients (browsers). This includes telling the browsers or other clients what type of document is being returned (e.g., HTML), setting cookies and caching parameters, and other such tasks.

参考:
Servlets - Overview: http://www.tutorialspoint.com/servlets/servlets_overview.htm

1.2 Servlet container (web container)

To deploy and run a servlet, a web container must be used. A web container (also known as a servlet container) is essentially the component of a web server that interacts with the servlets. The web container is responsible for managing the lifecycle of servlets, mapping a URL to a particular servlet and ensuring that the URL requester has the correct access rights.

1.3 Servlet version history

Table 1: Servlet API history
Servlet API version Released Platform Important Changes
Servlet 4.0 Sep 2017 Java EE 8 HTTP/2
Servlet 3.1 May 2013 Java EE 7 Non-blocking I/O, HTTP protocol upgrade mechanism (WebSocket)
       
Servlet 3.0 December 2009 Java EE 6, Java SE 6 Pluggability, Ease of development, Async Servlet, Security, File Uploading
Servlet 2.5 September 2005 Java EE 5, Java SE 5 Requires Java SE 5, supports annotation
Servlet 2.4 November 2003 J2EE 1.4, J2SE 1.3 web.xml uses XML Schema
Servlet 2.3 August 2001 J2EE 1.3, J2SE 1.2 Addition of Filter
Servlet 2.2 August 1999 J2EE 1.2, J2SE 1.2 Becomes part of J2EE, introduced independent web applications in .war files
Servlet 2.1 November 1998 Unspecified First official specification, added RequestDispatcher, ServletContext
Servlet 2.0   JDK 1.1 Part of Java Servlet Development Kit 2.0
Servlet 1.0 June 1997    

参考:https://en.wikipedia.org/wiki/Java_servlet#History

Servert 3.0新功能,可参考:
http://stackoverflow.com/questions/1638865/what-are-the-differences-between-servlet-2-5-and-3
http://javabeat.net/new-features-in-servlets-3-0/

2 Servlets Lifecycle

A servlet life cycle can be defined as the entire process from its creation till the destruction. The following are the paths followed by a servlet:

  • The servlet is initialized by calling the init () method.
  • The servlet calls service() method to process a client's request.
  • The servlet is terminated by calling the destroy() method.
  • Finally, servlet is garbage collected by the garbage collector of the JVM.

Now let us discuss the life cycle methods in details.

参考:
http://www.tutorialspoint.com/servlets/servlets-life-cycle.htm
http://docs.oracle.com/javaee/6/tutorial/doc/bnafi.html

2.1 The service() method

The service() method is the main method to perform the actual task. The servlet container (i.e. web server) calls the service() method to handle requests coming from the client( browsers) and to write the formatted response back to the client.

Each time the server receives a request for a servlet, the server spawns a new thread and calls service. The service() method checks the HTTP request type (GET, POST, PUT, DELETE, etc.) and calls doGet, doPost, doPut, doDelete, etc. methods as appropriate.

Here is the signature of this method:

public void service(ServletRequest request,
                    ServletResponse response)
      throws ServletException, IOException{
}

The service () method is called by the container and service method invokes doGe, doPost, doPut, doDelete, etc. methods as appropriate. So you have nothing to do with service() method but you override either doGet() or doPost() depending on what type of request you receive from the client.

2.2 Architecture Digram

The following figure depicts a typical servlet life-cycle scenario.

  • First the HTTP requests coming to the server are delegated to the servlet container.
  • The servlet container loads the servlet before invoking the service() method.
  • Then the servlet container handles multiple requests by spawning multiple threads, each thread executing the service() method of a single instance of the servlet.

servlet_lifecycle.jpg

Figure 1: Servlet life-cycle

3 Servlets Example: Hello World

Servlets are Java classes which service HTTP requests and implement the javax.servlet.Servlet interface. Web application developers typically write servlets that extend javax.servlet.http.HttpServlet, an abstract class that implements the Servlet interface and is specially designed to handle HTTP requests.

下面演示一个简单的servlet实例(Hello World):

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

// Extend HttpServlet class
public class HelloWorld extends HttpServlet {

  private String message;

  public void init() throws ServletException {
      // Do required initialization
      message = "Hello World";
  }

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException {
      // Set response content type
      response.setContentType("text/html");

      // Actual logic goes here.
      PrintWriter out = response.getWriter();
      out.println("<h1>" + message + "</h1>");
  }

  public void destroy() {
      // do nothing.
  }
}

编译上面的servlet程序:

$ export CLASSPATH=/path/to/tomcat/lib/servlet-api.jar:${CLASSPATH}
$ javac HelloWorld.java
$ ls
HelloWorld.class  HelloWorld.java

说明:编译程序前,servlet-api.jar应该配置到环境变量CLASSPATH中,否则会提示类似下面的错误:
package javax.servlet does not exist
package javax.servlet.http does not exist

可用下面步骤来部署上面编译好的servlet程序:
第1步,复制HelloWorld.class到<Tomcat-installation-directory>/webapps/ROOT/WEB-INF/classes
第2步,在配置文件<Tomcat-installation-directory>/webapps/ROOT/WEB-INF/web.xml中的<web-app>…</web-app>之间增加下面内容:

<servlet>
   <servlet-name>HelloWorld</servlet-name>
   <servlet-class>HelloWorld</servlet-class>
</servlet>

<servlet-mapping>
   <servlet-name>HelloWorld</servlet-name>
   <url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>

第3步,运行脚本<Tomcat-installation-directory>/bin/startup.sh启动tomcat。
第4步,测试,用浏览器访问 http://localhost:8080/HelloWorld ,可看到下面内容:

servlet_helloworld.jpg

Figure 2: Servlet example: Hello World

参考:http://www.tutorialspoint.com/servlets/servlets-first-example.htm

4 Servlet Filters

A filter is an object that can transform the header and content (or both) of a request or response. Filters differ from web components in that filters usually do not themselves create a response. Instead, a filter provides functionality that can be "attached" to any kind of web resource. Consequently, a filter should not have any dependencies on a web resource for which it is acting as a filter; this way, it can be composed with more than one type of web resource.

The main tasks that a filter can perform are as follows:

  • Query the request and act accordingly.
  • Block the request-and-response pair from passing any further.
  • Modify the request headers and data. You do this by providing a customized version of the request.
  • Modify the response headers and data. You do this by providing a customized version of the response.
  • Interact with external resources.

Applications of filters include authentication, logging, image conversion, data compression, encryption, tokenizing streams, XML transformations, and so on.

Note that filters are not servlets. They do not implement and override HttpServlet methods such as doGet() or doPost(). Rather, a filter implements the methods of the javax.servlet.Filter interface. The methods are: init(), destroy(), doFilter().

Servlet Filter工作原理如下:

servlet_filter.gif

Figure 3: Servlet Invocation with and without Filters

参考:
http://docs.oracle.com/javaee/6/tutorial/doc/bnagb.html
http://docs.oracle.com/cd/B14504_01/dl/web/B10321_01/filters.htm

4.1 web.xml中配置filter

和配置sevlet类似,我们可以在web.xml的<web-app>…</web-app>之间配置filter。如:

<filter>
   <filter-name>AuthenticationFilter</filter-name>
   <filter-class>com.xxx.servlet.filters.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>AuthenticationFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

上面例子中,所有请求都会先经过AuthenticationFilter的处理。

filter简单实例可参考:http://www.tutorialspoint.com/servlets/servlets-writing-filters.htm

5 Event Listeners

The servlet specification includes the capability to track key events in your Web applications through event listeners. This functionality allows more efficient resource management and automated processing based on event status.

参考:http://docs.oracle.com/cd/B14099_19/web.1012/b14017/filters.htm#i1000654

5.1 Event Listeners实例

下面例子摘自:https://www.mkyong.com/servlet/what-is-listener-servletcontextlistener-example/

首先,创建一个类。

package com.mkyong.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyAppServletContextListener implements ServletContextListener{

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
    System.out.println("ServletContextListener destroyed");
    }

    //Run this before web application is started
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("ServletContextListener started");
    }
}

然后,在web.xml中进行相关配置,例如:

<web-app ...>
  <listener>
    <listener-class>
       com.mkyong.listener.MyAppServletContextListener
    </listener-class>
  </listener>
</web-app>

启动tomcat后,会有类似下面的输出:

Dec 2, 2009 10:11:46 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.20

ServletContextListener started   <-------------- Your code here, before we application --->

Dec 2, 2009 10:11:46 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
//...
INFO: Server startup in 273 ms

Author: cig01

Created: <2015-11-15 Sun 00:00>

Last updated: <2018-03-02 Fri 22:43>

Creator: Emacs 25.3.1 (Org mode 9.1.4)