Java Servlet 是運行在 Web 服務器或應用服務器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務器上的數據庫或應用程序之間的中間層。
servlet是單例多線程的。也就是說,在堆內存中只有一份servlet對象。對於每一次http請求,servlet容器會自動調用servlet對象的service()方法去開辟線程,在這個線程中根據已有的url-class關系對這個request進行處理。
servlet需要跑在web服務器上。這里使用apache-tomcat-9.0.12。
servlet流程圖:
一、Servlet接口類
1.Servlet接口類及其方法
public interface Servlet
Defines methods that all servlets must implement.
A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet
or an HTTP servlet that extends javax.servlet.http.HttpServlet
.
This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence:
1.The servlet is constructed, then initialized with the init
method.
2.Any calls from clients to the service
method are handled.
3.The servlet is taken out of service, then destroyed with the destroy
method, then garbage collected and finalized.
In addition to the life-cycle methods, this interface provides the getServletConfig
method, which the servlet can use to get any startup information, and the getServletInfo
method, which allows the servlet to return basic information about itself, such as author, version, and copyright.
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. |
Servlet特性:
1.Servlet是單例多線程的,一個Servlet實例就是一次請求;
2.一個Servlet實例只會執行一次無參構造方法和init方法,並且是在第一次訪問時執行;
3.一個Servlet實例只會執行一次destroy方法,並且在應用停止時銷毀;
4.一個Servlet實例可以執行多個service,每當有用戶請求發生,就會執行一次service方法;
5.Servlet是單例(單例模式)多線程的,所以為了線程安全,不為其設置成員變量,以避免線程間篡改成員變量;
6.默認情況下,Servlet在web容器啟動時是不會被實例化的;
2.Servlet生命周期測試

package com.servlets; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * servlet的生命周期 * @author apple * @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5 * @see javax.servlet.Servlet * @see javax.servlet.ServletConfig */ public class ServletLifeCircleDemo implements Servlet { public ServletLifeCircleDemo() { System.out.println(" 1.執行構造方法......"); } @Override public void init(ServletConfig init) throws ServletException { System.out.println(" 2.初始化......"); } @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println(" 3.接受並處理請求......"); // 兩個方法 ServletConfig servletConfig = this.getServletConfig(); System.out.println(servletConfig); // 讀取配置信息 String servletInfo = this.getServletInfo(); System.out.println(servletInfo); } @Override public ServletConfig getServletConfig() { return null; } @Override public String getServletInfo() { return null; } @Override public void destroy() { System.out.println(" 銷毀: destroy"); } }

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <servlet> <servlet-name>Servlet-Life-Circle</servlet-name> <servlet-class>com.servlets.ServletLifeCircleDemo</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet-Life-Circle</servlet-name> <url-pattern>/servletLifeCircle</url-pattern> </servlet-mapping> </web-app>
啟動並訪問http://localhost:8080/servletLifeCircle。后台依次打印上述信息。也就是說,整個流程是constructor實例化servlet --> 執行init函數 --> 執行service方法。在整個服務關閉或停止時,會最后執行destroy方法。這里getServletConfig()和getServletInfo()返回null是因為重寫了接口設定返回值為null。
service是自動調用的,對外提供的請求和相應處理的方法。

1.執行構造方法......
2.初始化......
3.接受並處理請求......
null
null
二、ServletConfig接口類
1.ServletConfig接口類及其方法
public interface ServletConfig
A servlet configuration object used by a servlet container to pass information to a servlet during initialization.
Method Summary | |
---|---|
String |
getInitParameter(String name) Returns a String containing the value of the named initialization parameter, or null if the parameter does not exist. |
Enumeration |
getInitParameterNames() Returns the names of the servlet's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the servlet has no initialization parameters. |
ServletContext |
getServletContext() Returns a reference to the ServletContext in which the caller is executing. |
String |
getServletName() Returns the name of this servlet instance. |
servlet容器會在實例化Servlet對象后,立刻調用init()方法,前面可以看到Servlet.init()傳入的參數就是ServletConfig對象。ServletConfig負責讀取web.xml內容,並交給init進行初始化配置。
this.config.getInitParameter和this.config.getInitParameterNames是獲取單個url請求的配置信息。它返回的是String或者Enumeration。
this.config.getServletContext()是獲取全局的配置信息。它返回的是一個ServletContext對象,該對象有一堆方法。
2.ServletConfig演示

package com.servlets; import java.io.IOException; import java.util.Enumeration; import javax.servlet.*; /** * @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5, ServletConfig * ServletConfig提供了四個方法,它主要用於讀取配置信息 * 一個Servlet對應一個ServletConfig */ public class ServletConfigDemo implements Servlet { private ServletConfig config; @Override public void init(ServletConfig config) throws ServletException { // servlet容器將ServletConfig傳遞了進來,為了使用config,在初始化的時候把它賦給成員變量 this.config = config; System.out.println("config = " + this.config); } @Override public ServletConfig getServletConfig() { return config; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { // 在service中測試config的方法,總共就四個 // 1.測試getServletName() String servletName = config.getServletName(); System.out.println("servlet name = " + servletName); // 2.測試getServletContext() ServletContext servletContext = config.getServletContext(); System.out.println("servlet context = " + servletContext); // 3.測試getInitParameterNames()方法 Enumeration<String> names = config.getInitParameterNames();// 獲取所有的配置的name while (names.hasMoreElements()) { String name = names.nextElement(); String value = config.getInitParameter(name); // 4.測試getInitParameter()方法 System.out.println("init-param: name=" + name + ", " + "value=" + value); } } @Override public String getServletInfo() { // TODO Auto-generated method stub return null; } @Override public void destroy() { // TODO Auto-generated method stub } }

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <servlet> <servlet-name>Servlet-Config</servlet-name> <servlet-class>com.servlets.ServletConfigDemo</servlet-class> <init-param> <param-name>name</param-name> <param-value>Jan</param-value> </init-param> <init-param> <param-name>age</param-name> <param-value>20</param-value> </init-param> <init-param> <param-name>gender</param-name> <param-value>female</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Servlet-Config</servlet-name> <url-pattern>/servletConfig</url-pattern> </servlet-mapping> </web-app>
servletConfig的配置在web.xml中是由<init-param>標簽實現的,<init-param>標簽需要寫在<servlet>標簽中。因此,我們可以給每一個url視圖都寫上請求前的配置。但是url請求彼此之間是訪問不到各自的servletConfig的。
啟動服務並訪問http://localhost:8080/servletConfig,可以看到如下信息。

servlet name = Servlet-Config
servlet context = org.apache.catalina.core.ApplicationContextFacade@202520aa
init-param: name=gender, value=female
init-param: name=name, value=Jan
init-param: name=age, value=20
三、ServletContext
既然有了每個url請求的servletConfig配置。就有所有servlet的全局配置,其里面放置的鍵值對都能夠被所有url請求共享,這個接口就是ServletContext。
前面可以看到,ServletConfig對象是由servlet容器自動傳遞給init函數的。ServletConfig包含的三個方法:getInitParameter()和getInitParameters()、getServletContext()。前兩個是單個的url請求配置,由web.xml中的<servlet>標簽下的<init-param>標簽設置。后一個是全局的屬性配置,由web.xml中的<context-param>標簽直接配置。
1.ServletContext接口類及其方法
public interface ServletContext
Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.
There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog
and possibly installed via a .war
file.)
In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead.
The ServletContext
object is contained within the ServletConfig
object, which the Web server provides the servlet when the servlet is initialized
Method Summary | |
---|---|
Object |
getAttribute(String name) Returns the servlet container attribute with the given name, or null if there is no attribute by that name. |
Enumeration |
getAttributeNames() Returns an Enumeration containing the attribute names available within this servlet context. |
ServletContext |
getContext(String uripath) Returns a ServletContext object that corresponds to a specified URL on the server. |
String |
getContextPath() Returns the context path of the web application. |
String |
getInitParameter(String name) Returns a String containing the value of the named context-wide initialization parameter, or null if the parameter does not exist. |
Enumeration |
getInitParameterNames() Returns the names of the context's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the context has no initialization parameters. |
int |
getMajorVersion() Returns the major version of the Java Servlet API that this servlet container supports. |
String |
getMimeType(String file) Returns the MIME type of the specified file, or null if the MIME type is not known. |
int |
getMinorVersion() Returns the minor version of the Servlet API that this servlet container supports. |
RequestDispatcher |
getNamedDispatcher(String name) Returns a RequestDispatcher object that acts as a wrapper for the named servlet. |
String |
getRealPath(String path) Returns a String containing the real path for a given virtual path. |
RequestDispatcher |
getRequestDispatcher(String path) Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path. |
URL |
getResource(String path) Returns a URL to the resource that is mapped to a specified path. |
InputStream |
getResourceAsStream(String path) Returns the resource located at the named path as an InputStream object. |
Set |
getResourcePaths(String path) Returns a directory-like listing of all the paths to resources within the web application whose longest sub-path matches the supplied path argument. |
String |
getServerInfo() Returns the name and version of the servlet container on which the servlet is running. |
Servlet |
getServlet(String name) Deprecated. As of Java Servlet API 2.1, with no direct replacement. This method was originally defined to retrieve a servlet from a In lieu of this method, servlets can share information using the |
String |
getServletContextName() Returns the name of this web application corresponding to this ServletContext as specified in the deployment descriptor for this web application by the display-name element. |
Enumeration |
getServletNames() Deprecated. As of Java Servlet API 2.1, with no replacement. This method was originally defined to return an |
Enumeration |
getServlets() Deprecated. As of Java Servlet API 2.0, with no replacement. This method was originally defined to return an |
void |
log(Exception exception, String msg) Deprecated. As of Java Servlet API 2.1, use log(String message, Throwable throwable) instead. This method was originally defined to write an exception's stack trace and an explanatory error message to the servlet log file. |
void |
log(String msg) Writes the specified message to a servlet log file, usually an event log. |
void |
log(String message, Throwable throwable) Writes an explanatory message and a stack trace for a given Throwable exception to the servlet log file. |
void |
removeAttribute(String name) Removes the attribute with the given name from the servlet context. |
void |
setAttribute(String name, Object object) Binds an object to a given attribute name in this servlet context. |
一個web應用對應一個ServletContext對象,所有的servlet(這里指url)共享這個對象。
ServletContext對象既是全局的,包含了一些信息,又提供一個域屬性空間,供我們用來設置一些參數和值。即setAttribute、getAttribute、removeAttribute。
2.ServletContext演示

package com.servlets; import javax.servlet.*; import java.io.IOException; /** * @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5, ServletContext * 一個應用對應一個servletContext,servletContext的別名又叫做application context * 所有的servlet共享一個servletContext * servletContext內的屬性是全局性的,稱為域屬性空間 */ public class ServletContextDemo2 implements Servlet { private ServletConfig config; @Override public void init(ServletConfig servletConfig) throws ServletException { this.config = servletConfig; } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { ServletContext context = config.getServletContext(); // 3.測試servletContext的域屬性設置信息 String mobile = (String) context.getAttribute("mobile"); System.out.println("Context params: " + "mobile=" + mobile); String email = (String) context.getAttribute("email"); System.out.println("Context params: " + "email=" + email); // 4.重置或刪除域屬性的值 context.setAttribute("mobile", "7654321"); context.removeAttribute("email"); // 5.測試getContextPath()方法 String contextPath = context.getContextPath();// 應用的名稱,也就是servlet-app,這里不知道為什么沒有顯示 System.out.println("contextPath=" + contextPath); String realPath = context.getRealPath("/images"); System.out.println("realPath=" + realPath); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }

package com.servlets; import javax.servlet.*; import java.io.IOException; import java.util.Enumeration; /** * @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5, ServletContext * 一個應用對應一個servletContext,servletContext的別名又叫做application context * 所有的servlet共享一個servletContext * servletContext內的屬性是全局性的,是由web.xml中的context-param配置的 * 此外它有一個全局的域屬性,稱為域屬性空間,在域屬性里可以設置屬性值 */ public class ServletContextDemo1 implements Servlet { private ServletConfig config; @Override public void init(ServletConfig servletConfig) throws ServletException { this.config = servletConfig; } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { // 測試context的方法 ServletContext context = config.getServletContext(); // 1.測試context-param的配置信息ServletContext Enumeration<String> names = context.getInitParameterNames(); while (names.hasMoreElements()) { String name = names.nextElement(); String value = context.getInitParameter(name); System.out.println(name + " = " + value); } // 2.設置域屬性,先訪問servletContext,設置了這個屬性;再訪問servletConfig,發現已經有了這個屬性 context.setAttribute("email", "xxx@qq.com"); context.setAttribute("mobile", "13041234123"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <context-param> <param-name>author</param-name> <param-value>Zhang</param-value> </context-param> <context-param> <param-name>date</param-name> <param-value>2018-09-30</param-value> </context-param> <servlet> <servlet-name>Servlet-Context-1</servlet-name> <servlet-class>com.servlets.ServletContextDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet-Context-1</servlet-name> <url-pattern>/servletContext1</url-pattern> </servlet-mapping> <servlet> <servlet-name>Servlet-Context-2</servlet-name> <servlet-class>com.servlets.ServletContextDemo2</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet-Context-2</servlet-name> <url-pattern>/servletContext2</url-pattern> </servlet-mapping> </web-app
啟動服務,訪問路徑即結果如下:

// 第一次訪問http://localhost:8080/servletContext2
Context params: mobile=null
Context params: email=null
contextPath=
realPath=/Users/apple/eclipse-workspace/servlet-partOne/out/artifacts/servletLifeCircle_war_exploded/images
// 訪問http://localhost:8080/servletContext1
date = 2018-09-30
author = Zhang
// 第二次訪問http://localhost:8080/servletContext2
Context params: mobile=13041234123
Context params: email=xxx@qq.com
contextPath=
realPath=/Users/apple/eclipse-workspace/servlet-partOne/out/artifacts/servletLifeCircle_war_exploded/images
這里Context Path=空是因為IDEA中的Deployment對話框下的Application context設置成了 "/",輸入"/servlet-parthOne"會有相對路徑。
四、將Servlet寫成HttpServlet
1.通過抽象類將service和Servlet進行解耦
如果直接每次繼承Servlet類然后在service寫業務邏輯太危險了。init()、getServletConfig()都需要自己去寫。
此時可以寫一個抽象類繼承Servlet,在該抽象類中實現其余四個方法,只將service定義為抽象方法。子類直接繼承這個抽象,並且只需重寫service方法就好了。

import javax.servlet.*; import java.io.IOException; /** * "適配器設計模式": 在子類和接口類添加一層抽象類。抽象類實現接口類定義的部分方法,從而子類不必實現所有的接口類方法。 */ public abstract class GenericServlet implements Servlet { // 同樣把config存到成員變量里,子類通過getServletConfig方法來獲取config private ServletConfig config; @Override public void init(ServletConfig servletConfig) throws ServletException { this.config = servletConfig; } @Override public ServletConfig getServletConfig() { return config; } // 把service寫為抽象方法,並把該實現類定義為抽象類。在此抽象類中實現其它的接口方法,而不實現service這個抽象方法。 @Override public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException; @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
子類繼承GenericServlet。

import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; public class SubServletDemo extends GenericServlet { // 子類只需要實現service就行了 @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("執行servletDemo"); ServletConfig config = this.getServletConfig(); // 獲取config // System.out.println(config); System.out.println( "name=" + config.getInitParameter("name") + ", age=" + config.getInitParameter("age") ); } }
2.重寫servletConfig方法
在上例中,config.getInitParameter()等價於this.getServletConfig().getInitParameter(),由於GenericService沒有實現這個方法,所以又需要訪問init中傳入的config的方法。為了保持各個service的獨立性,應該讓GenericService中繼承servletConfig並重寫其中的四個方法。

import javax.servlet.*; import java.io.IOException; import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig { // 同樣把config存到成員變量里,子類通過getServletConfig方法來獲取config private ServletConfig config; @Override public void init(ServletConfig servletConfig) throws ServletException { this.config = servletConfig; init();// 啟動子類的init初始化設置 } // "模板方法設計模式" // 讓子類用這個init public void init(){} @Override public ServletConfig getServletConfig() { return config; } // 把service寫為抽象方法,並把該實現類定義為抽象類。在此抽象類中實現其它的接口方法,而不實現service這個抽象方法。 @Override public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException; @Override public String getServletInfo() { return null; } @Override public void destroy() { } // 直接繼承重寫ServletConfig的四個方法 @Override public String getServletName() { return config.getServletName(); } @Override public ServletContext getServletContext() { return config.getServletContext(); } @Override public String getInitParameter(String s) { return config.getInitParameter(s); } @Override public Enumeration<String> getInitParameterNames() { return config.getInitParameterNames(); } }
同時,為了不破壞init(ServletConfig config)函數,再重載一個init()給子類用即可。這樣能保證在serlvet實例化時,同樣使子類(service處理類)也能夠自由的初始化。
3.GET請求和POST請求解耦
前面SubServletDemo繼承了自己寫的抽象父類GenericServlet(繼承了Servlet和ServletConfig),並且實現了父類service方法。如果需要根據GET請求和POST請求分開處理,需要改寫成這樣:

import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class LoginServlet extends GenericServlet{ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("login HttpServletBase ......"); // 獲取請求方式 HttpServletRequest request = (HttpServletRequest) servletRequest; // 強轉 HttpServletResponse response = (HttpServletResponse) servletResponse; String method = request.getMethod(); System.out.println("method=" + method); // 定義get和post方法,用來調用不同的處理方式 if("GET".equals(request)){ doGet(request, response); }else if("POST".equals(response)){ doPost(request, response); } } private void doPost(HttpServletRequest request, HttpServletResponse response) { System.out.println("POST 提交......"); } private void doGet(HttpServletRequest request, HttpServletResponse response) { System.out.println("GET 提交"); } }
顯然這種寫法有些陋。我們進行如下改寫,並將SubServletDemo重命名為HttpServlet。

import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /* "模板設計模式":以后只用doPost或者doGet來處理get請求或者post請求 */ public class HttpServlet extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("login HttpServletBase ......"); // 獲取請求方式 HttpServletRequest request = (HttpServletRequest) servletRequest; // 強轉 HttpServletResponse response = (HttpServletResponse) servletResponse; service(request, response); } public void service(HttpServletRequest request, HttpServletResponse response){ String method = request.getMethod(); System.out.println("method=" + method); if ("GET".equals(request)) { doGet(request, response); } else if ("POST".equals(response)) { doPost(request, response); } } // public void doPost(HttpServletRequest request, HttpServletResponse response) { } public void doGet(HttpServletRequest request, HttpServletResponse response) { } }
最后寫一個只有GET請求和POST請求的處理類,讓它繼承HttpServlet:

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet{ public void doPost(HttpServletRequest request, HttpServletResponse response) { System.out.println("POST 提交......"); } public void doGet(HttpServletRequest request, HttpServletResponse response) { System.out.println("GET 提交"); } }
五、GenericServlet和HttpServlet
上一節手動寫了一遍GenericServlet.class和HttpServlet.class。實際上,在serlvet中導入javax.servlet.http.HttpServlet直接使用即可:

import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /* 直接使用javax.HttpServletBase.http.HttpServletBase */ public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("GET 提交......"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("POST 提交......"); } }
1.GenericServlet類
public abstract class GenericServletextends Objectimplements Servlet, ServletConfig, Serializable
Defines a generic, protocol-independent servlet. To write an HTTP servlet for use on the Web, extend HttpServlet
instead.
GenericServlet
implements the Servlet
and ServletConfig
interfaces. GenericServlet
may be directly extended by a servlet, although it's more common to extend a protocol-specific subclass such as HttpServlet
.
GenericServlet
makes writing servlets easier. It provides simple versions of the lifecycle methods init
and destroy
and of the methods in the ServletConfig
interface. GenericServlet
also implements the log
method, declared in the ServletContext
interface.
To write a generic servlet, you need only override the abstract service
method.
Method Summary | |
---|---|
void |
destroy() Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. |
String |
getInitParameter(String name) Returns a String containing the value of the named initialization parameter, or null if the parameter does not exist. |
Enumeration |
getInitParameterNames() Returns the names of the servlet's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the servlet has no initialization parameters. |
ServletConfig |
getServletConfig() Returns this servlet's ServletConfig object. |
ServletContext |
getServletContext() Returns a reference to the ServletContext in which this servlet is running. |
String |
getServletInfo() Returns information about the servlet, such as author, version, and copyright. |
String |
getServletName() Returns the name of this servlet instance. |
void |
init() A convenience method which can be overridden so that there's no need to call super.init(config) . |
void |
init(ServletConfig config) Called by the servlet container to indicate to a servlet that the servlet is being placed into service. |
void |
log(String msg) Writes the specified message to a servlet log file, prepended by the servlet's name. |
void |
log(String message, Throwable t) Writes an explanatory message and a stack trace for a given Throwable exception to the servlet log file, prepended by the servlet's name. |
abstract void |
service(ServletRequest req, ServletResponse res) Called by the servlet container to allow the servlet to respond to a request. |
與第四節寫的GenericServlet幾乎一致。
2.HttpServlet類
public abstract class HttpServlet extends GenericServlet implements Serializable
Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet
must override at least one method, usually one of these:
-
doGet
, if the servlet supports HTTP GET requests -
doPost
, for HTTP POST requests -
doPut
, for HTTP PUT requests -
doDelete
, for HTTP DELETE requests -
init
anddestroy
, to manage resources that are held for the life of the servlet -
getServletInfo
, which the servlet uses to provide information about itself
There's almost no reason to override the service
method. service
handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the do
XXX methods listed above).
Likewise, there's almost no reason to override the doOptions
and doTrace
methods.
Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections. See the Java Tutorial on Multithreaded Programming for more information on handling multiple threads in a Java program.
Method Summary | |
---|---|
protected void |
doDelete(HttpServletRequest req, HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a DELETE request. |
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 |
doHead(HttpServletRequest req, HttpServletResponse resp) Receives an HTTP HEAD request from the protected service method and handles the request. |
protected void |
doOptions(HttpServletRequest req, HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a OPTIONS 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 |
doPut(HttpServletRequest req, HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a PUT request. |
protected void |
doTrace(HttpServletRequest req, HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a TRACE request. |
protected long |
getLastModified(HttpServletRequest req) Returns the time the HttpServletRequest object was last modified, in milliseconds since midnight January 1, 1970 GMT. |
protected void |
service(HttpServletRequest req, HttpServletResponse resp) Receives standard HTTP requests from the public service method and dispatches them to the do XXX methods defined in this class. |
void |
service(ServletRequest req, ServletResponse res) Dispatches client requests to the protected service method. |
上節只實現了doGet和doPost,但是邏輯都是相同的。