Servlet(Server Applet)是Java Servlet的簡稱,是爲小服務程序或服務鏈接器,用Java編寫的服務器端程序,主要功能在於交互式地瀏覽和修改數據,生成動態Web內容。html
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.
(servlet是一個java小程序運行在web服務器。servlet接收並響應來自Web客戶端的請求,一般經過HTTP,超文本傳輸協議。)java
(1)客戶端發送請求至服務器端;web
(2)服務器將請求信息發送至 Servlet;數據庫
(3)Servlet 生成響應內容並將其傳給服務器。響應內容動態生成,一般取決於客戶端的請求;小程序
(4)服務器將響應返回給客戶端。緩存
(1)動態生成HTML文檔。服務器
(2)將請求轉發給Servlet組件。markdown
(3)讀取客戶端的Cookie,以及向客戶端寫入Cookie。app
(4)訪問服務器的資源,如數據庫、 XML、文件對像等。框架
(1)Servlet對像,由Servlet容器(Tomcat)建立。
(2)Servlet是一個接口:位於javax.servlet包中。
(3)service方法用於接收用戶的請求並返回響應。
(4)用戶訪問時屢次被執行(能夠統計網站的訪問量)。
Servlet接口:
package cn.hncu; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class FirstServlet implements Servlet { /**init方法*/ @Override public void init(ServletConfig paramServletConfig) throws ServletException { } /**getServletConfig方法*/ @Override public ServletConfig getServletConfig() { return null; } /**service方法*/ @Override public void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse) throws ServletException, IOException { } /**getServletInfo方法*/ @Override public String getServletInfo() { return null; } /**destroy方法*/ @Override public void destroy() { } }
GenericServlet類:
package cn.hncu; import java.io.IOException; import javax.servlet.GenericServlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /**【注意】GenericServlet是抽象類,service是抽象方法*/ public class ExtendGenericServlet extends GenericServlet { /**service方法*/ /**【注意】惟獨service方法沒有被實現,這個service方法咱們本身使用*/ @Override public void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse) throws ServletException, IOException { } /**destroy方法*/ /**【注意】除過service方法以外,其餘方法都已經被實現了,而且這些方法都調用父接口的方法*/ @Override public void destroy() { super.destroy(); } /**getServletConfig方法*/ @Override public ServletConfig getServletConfig() { return super.getServletConfig(); } /**getServletInfo方法*/ @Override public String getServletInfo() { return super.getServletInfo(); } /**init方法*/ @Override public void init(ServletConfig config) throws ServletException { super.init(config); } /**【注意】:若是咱們覆蓋帶參數的init父類方法時候,沒有寫super.init(config)這一句: public void init(ServletConfig config) throws ServletException { } 咱們的程序會出現空指針異常錯誤: 嚴重: Servlet.service() for servlet [ExtendsGenericServlet] in context with path [/useServlet] threw exception java.lang.NullPointerException at javax.servlet.GenericServlet.getInitParameterNames(GenericServlet.java:99) at cn.hncu.ExtendsGenericServlet.service(ExtendsGenericServlet.java:53) 咱們知道,此時getInitParameterNames是空指針,咱們去API中查看,關於getInitParameterNames的來源, 若是來源的某一地方是空指針,則就說明這個地方值爲空! 咱們依次點擊這些類的關聯: public Enumeration<String> getInitParameterNames() { return getServletConfig().getInitParameterNames(); } ----》說明:getServletConfig()爲NULL public ServletConfig getServletConfig() { return this.config; } ----》說明:config爲NULL public void init(ServletConfig config) throws ServletException { this.config = config; init(); } ----》說明:此處就是問題的根源:config沒有賦值 ----》也說明:帶參數的init方法沒有被執行 ----》由於咱們在父類方法的時候,正好將父類的方法:init(config)給刪除了 ----》因此覆蓋父類方法的時候這句必定要寫! //GenericServlet類中有一個空參init()方法, //實際上是適配器模式中的一個技術細節:在帶參init方法中幫咱們把config賦好值, //而後調用空參且空實現init()方法--該方法是專門給子類覆蓋的。 //---在適配器中幫咱們作一部分事情,而後調用咱們的覆蓋方法 }
HttpServlet類:
package cn.hncu; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ExtendHttpServlet extends HttpServlet { /**service方法*/ /**【注意】此service方法是HttpServlet類 繼承 GenericServlet類 後實現的其抽象service方法的*/ @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.service(req, resp); } /**destroy方法*/ /**【注意】下面的這些方法所有是繼承與GenericServlet類中的方法*/ @Override public void destroy() { super.destroy(); } /**getServletConfig方法*/ @Override public ServletConfig getServletConfig() { return super.getServletConfig(); } /**getServletInfo方法*/ @Override public String getServletInfo() { return super.getServletInfo(); } /**init方法*/ @Override public void init(ServletConfig config) throws ServletException { super.init(config); } }
只會被初始化一次,由容器初始化,初始化成功後將緩存與容器中。
它的初始時間分爲兩種:
用戶第一次訪問時。
服務器啓動時,須要配置。
每次請求都會訪問此方法。
每次請求都會建立新的Request和Response對像。
當服務器關閉時由容器調用並銷燬。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>測試Servlet的生命週期</title> </head> <body> <h2>測試Servlet的生命週期</h2> <a href="servlet/TestServlet">測試servlet的生命週期</a> </body> </html>
package cn.hncu; 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 user * */ public class TestServlet implements Servlet { /*** 【注意】這裏是咱們本身實現的Servlet接口,所以每一個方法的返回值都是咱們本身決定的。 因爲另外一個方法中getServletConfig()中返回值是NULL,所以須要將init方法中的ServletConfig參數賦值給getServletConfig的結果。 即:咱們定義私有類成員變量:config 在init方法中讓:this.config=paramServletConfig; */ private ServletConfig config; @Override public void init(ServletConfig paramServletConfig) throws ServletException { this.config=paramServletConfig; System.out.println("init方法執行...."); } @Override public ServletConfig getServletConfig() { System.out.println("getServletConfig方法執行...."); return config; } @Override public void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse) throws ServletException, IOException { System.out.println("service方法執行...."); ServletConfig config = getServletConfig(); String info = getServletInfo(); } @Override public String getServletInfo() { System.out.println("getServletInfo方法執行"); return null; } @Override public void destroy() { System.out.println("destroy方法執行...."); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" 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_3_0.xsd"> <display-name></display-name> <servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>cn.hncu.TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TestServlet</servlet-name> <url-pattern>/servlet/TestServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" 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_3_0.xsd"> <display-name></display-name> <servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>cn.hncu.TestServlet</servlet-class> <!-- 在啓動在啓動時加載元件負載指示就加載這個servlet(實例化並調用其())對Web應用程序的啓動。 這些元素的可選內容必須是一個整數,指示應加載servlet的順序。 若是值是負整數,或者元素不存在,容器能夠自由加載servlet。 若是該值是正整數或0,則容器必須在部署應用程序時加載和初始化servlet。 容器必須保證servlet標有低整數在servlet標有高整數裝。 容器可選擇順序加載Servlet具備相同的負載啓動值。 --> <load-on-startup>20</load-on-startup> </servlet> <servlet-mapping> <servlet-name>TestServlet</servlet-name> <url-pattern>/servlet/TestServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>