1. 程式人生 > >06.實現servlet的幾種方式,以及接口或者類之間的關系

06.實現servlet的幾種方式,以及接口或者類之間的關系

ssa 圖片 servlet 容器 實例化 設備 blog public ide

接口:Servlet、ServletConfig、ServletRequest、ServletResponse、HttpServletRequest、HttpServletResponse、ServletContext

類:HttpServlet(抽象類)、GenericServlet(抽象類)

來張關系圖
技術分享

ServletContext:

ServletContext的對象是application是在項目初始化時被創建的。故servletContext隨著應用初始化而被創建,隨著應用的結束而被銷毀。

ServletConfig :

 在應用初始化的時候,Web容器在創建Servlet對象時會自動將web.xml中的servlet配置這些初始化參數封裝到ServletConfig對象中,並在調用servlet
 的init方法時,將ServletConfig對象傳遞給servlet。所以我們可以通過ServletConfig對象就可以得到當前servlet的初始化參數信息。

Servlet:

初始化有兩種情況:

 一、隨應用初始化時初始化,即在web.xml中設置<load-on-startup>參數</load-on-startup>,參數為整數值並且大於0,而且值越少,優先級越高。
 在springmvc項目中經常會用到這個配置
二、在應用運行中時,servlet被客戶端請求時初始化。

servlet銷毀:

servlet自身調用destroy()方法、servlet容器停止運行、項目停止運行都會銷毀該servlet實例。

ServletRequest:

ServletRequest的對象是request,其生命周期為request域,一個請求結束,則request對象結束。

ServletResponse:

ServletResponse的對象是response,一次響應結束,則response對象結束。

HttpServlet和HttpServletRequest、HttpServletResponse

他們之間的關系就好像Servlet和ServletRequest、ServletResponse之間的關系一樣,只不過做了少部分封裝而已

(附加)請求的響應方式有四種:

request.getRequestDispatcher("*.jsp").forward(request, response) //轉發
response.sendRedirect("*.jsp")//重定向
response.getOutputStream()//流
response.getWriter()//直接響應





















看示意圖:

技術分享

1.繼承GenericServlet

public class TestServlet extends GenericServlet {

    private static final long serialVersionUID = 1L;

    @Override
    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException {

    }
}
--------------------------------------------------------
GenericServlet--抽象類,實現了Servlet接口

public abstract class GenericServlet 
    implements Servlet, ServletConfig, java.io.Serializable
{

    private transient ServletConfig config;
    .........
    .........
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

2.繼承HttpServlet

好爽,request,response,config,都是現成的,service方法已經被重寫,只需要根據需求調用 doGet() 或者doPost() 方法即可!!!

public class TestServlet2 extends HttpServlet {


    public TestServlet2() {
        super();
    }

    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
    }

    public void doDelete(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }

    public void doPut(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }
    public void init() throws ServletException {
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

HttpServlet
這個類繼承GenericServlet類,實現了Java.io.Serializable的接口,它是個抽象類,給其子類創建一個Http Servlet去適應一個網站。
而HttpServlet的子類必須重寫至少一個方法,其中較為經常修改的方法有:
1、如果你希望servlet支持HTTP的Get請求,重寫doGet方法

2、如果你希望servlet支持HTTP的Post請求,重寫doPost方法

3、如果你希望servlet不但可以處理數據,還可以處理文件,重寫doPut方法。Put的調用和Post相似,它允許客戶端把真正的文件存放在服務器上,而不僅僅是傳送數據

4、如果你希望servlet允許客戶端刪除服務器端的文件或者Web頁面,重寫doDelete方法,它與Put相似。

5、如果你希望控制servlet生命周期所產生的資源,可以重寫init和destroy方法

6、如果你希望servlet提供關自身的相關信息,可以調用或重寫javax.servlet.http.HttpServlet類繼承javax.servlet.GenericServlet類的getServletInfo方法。

public abstract class HttpServlet extends GenericServlet
    implements java.io.Serializable {
    }
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

3.實現Servlet接口

public class TestServlet implements Servlet {


    private static final long serialVersionUID = 1L;


    public void destroy() {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public String getServletInfo() {
        return null;
    }

    public void init(ServletConfig config) throws ServletException {

    }

    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException {

    }

}

是不是很不爽,需要重寫這麽多方法!!!





首先明確,Servlet並不是專門用於處理Http請求的。然後再說三種方式的聯系和區別。
1)原生Servlet接口
package javax.servlet;

import java.io.IOException;


public interface Servlet {

    public void init(ServletConfig config) throws ServletException;
    
    public ServletConfig getServletConfig();
    

    public void service(ServletRequest req, ServletResponse res)
	throws ServletException, IOException;
	
    public String getServletInfo();
    

    public void destroy();
}
可以看到Servlet接口是定義在javax.servlet包中,該接口定義了5個方法。
init() :在Servlet實例化之後,Servlet容器會調用init()方法,來初始化該對象,主要是為了讓Servlet對象在處理客戶請求之前可以完成一些初始化工作,比如:建立數據庫的連接,獲取配置信息。

service():容器調用service()方法來處理客戶端的請求。

destroy():當容器檢測到一個Servlet對象應該從服務器中被移除的時候,容器會調用該對象的destroy方法,以便讓Servlet對象可以釋放它所使用的資源,保存數據到持久化存儲設備中,例如:將內存中的數據保存到數據庫中,關閉數據庫的連接。

2)GenericServlet
為什麽會出現GenericServlet?如果我們直接通過實現Servlet接口來編寫一個Servlet類,就需要實現Servlet接口中定義的5種方法,為了簡化Servlet的編寫,在javax.servlet包中,給我們提供了一個抽象的類GenericServlet,它提供了除service()方法外的其他4種方法的簡單實現。GenericServlet類定義了一個通用的,不依賴具體協議的Servlet
package javax.servlet;

import java.io.IOException;
import java.util.Enumeration;
import java.util.ResourceBundle;

public abstract class GenericServlet 
    implements Servlet, ServletConfig, java.io.Serializable
{
    private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
    private static ResourceBundle lStrings =
        ResourceBundle.getBundle(LSTRING_FILE);

    private transient ServletConfig config;
    

    public GenericServlet() { }
    
    
    public void destroy() {
    }
    
    
    public String getInitParameter(String name) {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getInitParameter(name);
    }
    
    
    public Enumeration<String> getInitParameterNames() {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getInitParameterNames();
    }   
     
   
    public ServletConfig getServletConfig() {
	return config;
    }
 
    public ServletContext getServletContext() {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getServletContext();
    }

    public String getServletInfo() {
	return "";
    }


    public void init(ServletConfig config) throws ServletException {
	this.config = config;
	this.init();
    }


    public void init() throws ServletException {

    }
    

      
    public void log(String msg) {
	getServletContext().log(getServletName() + ": "+ msg);
    }
   

    public void log(String message, Throwable t) {
	getServletContext().log(getServletName() + ": " + message, t);
    }
    
    public abstract void service(ServletRequest req, ServletResponse res)
	throws ServletException, IOException;
    
    public String getServletName() {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(
                lStrings.getString("err.servlet_config_not_initialized"));
        }

        return sc.getServletName();
    }
}

3)HttpServlet
由於大多數網絡應用中,都是瀏覽器通過HTTP協議去訪問服務器資源,而我們編寫的Servlet也主要是應用於HTTP協議的請求和響應,為了快速開發應用於HTTP協議的Servlet,Sun公司在javax.servlet.http包中給我們提供了一個抽象的類HttpServlet,他繼承自GenericServlet類,用於創建適合Web站點的HTTP Servlet。

比如,doPost doGet這些方法,從request解析請求信息開始,將根據http協議的格式進行解析,分發到不同的請求方法處理中,doPost doGet也肯定是被service方法調用的。

06.實現servlet的幾種方式,以及接口或者類之間的關系