Web核心-Servlet

Servlet其實是ServerApplet--小服務程序或服務鏈接器,用Java編寫的服務器端程序,主要功能在於交互式地瀏覽和修改數據,生成動態Web內容。與經常使用的協議,如DNS,TCP/IP,HTTP相似,Servlet是做爲一整套規範存在的;同時做爲J2EE標準的一部分,定義了javaweb開發的標準。Servlet制定了java處理WEB請求的一系列標準,咱們只須要按照標準規定的去作就能夠了。
實際上,不管是Struts2的FilterDispatcher仍是SpringMvc的DispatcherServlet,其底層都是經過實現Sevlet或者Servlet類型的擴展【如:GenericServlet】來實現的。java

1.Servlet接口

下圖爲Servlet3.1中的結構圖:
web


由於Servlet是以規範的方式存在的,實際上就是定義一系列規範接口。在Servlet接口中,主要包括如下幾個接口:

1)init方法是在容器啓動時被容器調用,且只會被調用一次;
2)getServletConfig方法用於獲取ServletConfig;
3)service方法用於處理一個具體的請求
4)getServletInfo方法用於獲取Servlet相關的信息:版權等。
5)destroy方法用來銷燬一個Servlet,和init同樣,只會被調用一次,通常在服務器關閉時用於釋放一些資源。

init方法調用時會接受一個ServletConfig類型的參數,用於初始化Servlet,由容器傳入。ServletConfig,顧名思義,其包含了Serlvet的配置信息。一般狀況下,咱們在web.xml文件中定義Serlvet時,會經過init-param標籤來進行參數配置。在Springmvc的配置中,一般經過如下方式來配置參數:
spring

2.ServletConfig接口


1)getServletName用於獲取Servlet的名字,也就是咱們在web.xml中定義的servlet-name
2)getServletContext返回ServletContext,表明咱們當前應用自己
3)getInitParameter用於獲取init-param配置的參數
4)getInitParameterNames用於獲取全部init-param配置名字的集合
ServletContext和ServletConfig最多見的使用就是傳遞初始化參數。來看下spring中的contextConfigServlet的參數配置

經過context-param配置的contextConfigLocation配置到了ServletContext中,再經過Servlet下的init-param配置的contextConfigLocation配置到ServletConfig中,在Servlet中能夠經過getInitParameter方法獲取具體的信息。

3.GenericServlet

GenericServlet是Servlet的默認實現,代碼以下:bash

package javax.servlet;
import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.ResourceBundle;
public abstract class GenericServlet
  implements Servlet, ServletConfig, Serializable
{
  private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
  private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
  private transient ServletConfig config;
  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 getInitParameterNames()
  {
    ServletConfig sc = getServletConfig();
    if (sc == null) {
      throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
    }
    return sc.getInitParameterNames();
  }
  public ServletConfig getServletConfig()
  {
    return this.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;
    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 paramServletRequest, ServletResponse paramServletResponse)
    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();
  }
}複製代碼

從其繼承和實現關係來看,GenericServlet主要作了3件事:
1.實現了ServletConfig接口,這樣咱們就能夠直接調用ServletConfig裏面的方法;
GenericServlet實現了ServletConfig,能夠在須要的時候直接調用ServletConfig中的方法,不須要再先獲取ServletConfig對象;好比,獲取ServletContext的時候能夠直接調用getServletContext,而無需調用getServletConfig().getServletContext(),可是實際上,其底層的內部實現仍是在內部仍是進行了getServletConfig().getServletContext()的調用。
服務器


2.提供了無參的init方法
GenericServlet實現了Servlet的init(ServletConfig config)方法,在裏面將config設置給了其內部變量config,而後調用了無參的init方法;此方法能夠在子類中經過覆蓋它來完成初始化工做。

這種方式具備的有點包括如下幾點:
a.config設置爲內部屬性,這樣能夠在ServletConfig的接口方法中直接調用Config的相應方法來執行;
b.咱們在寫Serlvet的時候能夠不用再關心Config,只須要執行本身的初始化邏輯便可
c.在重寫init方法時,不須要再調用super.init(config)。
3.提供了Log方法
GenericServlet提供了2個log方法,一個用於記錄日誌,一個用於記錄異常。其具體的實現是經過傳給ServletConfig的日誌實現的。
GenericServlet是與具體協議無關的。

4.HttpServlet

HttpServlet是基於Http協議實現的Servlet的基類,寫Servlet時直接繼承HttpServlet便可,不須要再重頭實現Servlet接口,SpringMvc中的dispatcherServlet就是HttpServlet的子類。 HttpServlet是與Http協議相關的,HttpServlet處理請求主要是經過重寫父類的service方法來完成具體的請求處理的。在service方法中首先是將ServletRequest和ServletResponse轉換成HttpServletRequest和HttpServletResponse,而後根據請求的不一樣路由到不一樣的處理過程當中去【處理方法就是咱們常見的doXXX的方法。最多見的就是doGet和doPost】
mvc

相關文章
相關標籤/搜索