1. 程式人生 > >javaWeb學習日記_16:servlet詳細解釋

javaWeb學習日記_16:servlet詳細解釋

1. 什麼是Servlet
  * Servlet是JavaWeb三大元件之一(Servlet、Filter、Listener)
  * Servlet是用來處理客戶端請求的動態資源
  * Servlet的任務有:

  •     獲取請求資料
  •     處理請求
  •     完成響應

  * Servlet介面方法:

  •     void init(ServletConfig)
  •      void service(ServletRequest,ServletResponse)
  •      void destory()
  •      ServletConfig getServletConfig()
  •      String getServletInfo()

2. 實現Servlet的方式

  •   實現Servlet介面(不方便)
  •    繼承GenericServlet類(不方便)
  •   繼承HttpServlet類(方便)

3. Servlet第一例

  •   寫一個類cn.itcast.MyServlet,實現Servlet介面
  •   實現service()方法,在其中給出System.out.println("hello servlet!");
  •   在web.xml檔案中指定Servlet的訪問路徑為:/myservlet
<servlet>
  <servlet-name>xxx</servlet-name>
  <servlet-class>cn.itcast.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>xxx</servlet-name>
  <url-pattern>/myservlet</url-pattern>
</servlet-mapping>


  當用戶在位址列中訪問:http://localhost:8080/day04_1/myservlet時,會執行System.out.println("hello servlet!");

===============================

4,Servlet生命週期

  Servlet介面一共5個方法,但其中只有三個是生命週期方法:

  •    void init(ServletConfig)
  •   void service(ServletRequest,ServletResponse)
  •   void destory()

  1). 伺服器建立Servlet:
  * 當Servlet第一次被請求時,或伺服器啟動時,伺服器會建立Servlet例項。
  * 伺服器預設是在servlet第一次被請求時建立Servlet例項,如果希望伺服器啟動時就建立Servlet實現需要在web.xml中配置
  * 伺服器只為一個型別的Servlet建立一個例項物件,所以Servlet是單例的;

  2). 伺服器初始化Servlet:

  •    當伺服器建立Servlet例項後會馬上呼叫Servlet的init(ServletConfig)方法,完成對Servlet的初始化;
  •   init(ServletConfig)只會被呼叫一次
  •   伺服器會在呼叫init()方法時傳遞ServletConfig引數

  
  3). 伺服器使用Servlet處理請求:

  •   當Servlet被請求時,伺服器會呼叫Servlet的service(ServletRequest,ServletResponse)方法
  •    service(ServletRequest,ServletResponse)方法每處理一次請求,就會被呼叫一次,所以它可能會被呼叫N次
  •    因為Servlet是單例的,所以可能在同一時刻一個Servlet物件會被多個請求同時訪問,所以這可能出現執行緒案例問題
  •   Servlet不是執行緒案例的,這有助與提高效率,但不能讓Servlet具有狀態,以免多個執行緒爭搶資料

  4). 伺服器銷燬Servlet

  •    伺服器通常不會銷燬Servlet,通常只有在伺服器關閉時才會銷燬Servlet
  •    伺服器會在銷燬Servlet之前呼叫Servlet的destory()方法
  •   可以在destory()方法中給出釋放Servlet佔有的資源,但通常Servlet是沒什麼可要釋放的,所以該方法一般都是空的

===============================

,5,ServletConfig

  ServletConfig是Servlet中的init()方法的引數型別,伺服器會在呼叫init()方法時傳遞ServletConfig物件給init()方法。
  ServletConfig物件封裝了Servlet在web.xml中的配置資訊,它對應<servlet>元素。ServletConfig類的功能有:

  •    String getServletName():獲取Servlet配置名,即<servlet-name>的值;
  •   ServletContext getServletContext():獲取ServletContext物件,這個物件稍後介紹
  •    String getInitParameter(String name):獲取初始化引數
  •    Enumeration getInitParameterNames():獲取所有初始化引數的名稱

  在web.xml檔案中,配置<servlet>時可以為<servlet>配置0~N個初始化引數,例如:

<servlet>
  <servlet-name>xxx</servlet-name>
  <servlet-class>cn.itcast.servlet.MyServlet</servlet-class>
  <init-param>
    <param-name>p1</param-name>
    <param-value>v1</param-value>
  </init-param>
  <init-param>
    <param-name>p2</param-name>
    <param-value>v2</param-value>
  </init-param>
</servlet>

===============================

6,GenericServlet

  GenericServlet是Servlet介面的實現類,但它是一個抽象類,它唯一的抽象方法就是service()方法
  GenericServlet實現了Servlet方法:

  •   實現了String getServletInfo()方法
  •   實現了void destory()方法,空實現
  •   實現了void init(ServletConfig)方法,用來儲存ServletConfig引數
  •   實現了ServletConfig getServletConfig()方法

  GenericServlet實現了ServletConfig介面:

  •    實現了ServletContext getServletContext()方法
  •    實現了String getInitParameter()方法
  •    實現了String getServletName()方法
  •    實現了Enumeration getInitParameterNames()方法

  GenericServlet添加了init()方法:

  •    該方法會被init(ServletConfig)方法呼叫
  •   如果希望對Servlet進行初始化,那麼應該覆蓋init()方法,而不是init(ServletConfig)方法

===============================

7,HttpServlet
  
  HttpServlet是GenericServlet的子類,它專注HTTP請求
  HttpServlet類的方法:
  1》 實現了void service(ServletRequest,ServletResponse)方法,實現內容是:

  •      把ServletRequest強轉成HttpServletRequest
  •      把ServletResponse強轉成HttpServletResponse
  •      呼叫本類新增的void service(HttpServletRequest,HttpServletResponse)方法

  2》添加了void service(HttpServletRequest,HttpServletResponse)方法,內容是:

  •     呼叫request的getMethod()獲取請求方式
  •      如果請求方式為GET,那麼呼叫本類新增的doGet(HttpServletRequest,HttpServletResponse)方法
  •      如果請求方式為POST,那麼呼叫本類新增的doPost(HttpServletRequest,HttpServletResponse)方法

  3》 添加了doGet(HttpServletRequest,HttpServletResponse)方法,內容是響應405,表示錯誤,所以我們應該去覆蓋這個方法
  4》添加了doPost(HttpServletRequest,HttpServletResponse)方法,內容是響應405,表示錯誤,所以我們應用去覆蓋這個方法

 如果是通過繼承HttpServlet類來自定義Sevlet的話,那麼:

  •    不要去覆蓋void service(ServletRequest,ServletResponse)
  •    不要去覆蓋void service(HttpServletRequest, HttpServletResponse)
  •   *而應該去覆蓋doGet()或doPost()方法。

===============================

7,<url-pattern>

  <url-pattern>是<servlet-mapping>的子元素,用來繫結Servlet的訪問路徑
  可以在一個<servlet-mapping>中給出多個<url-pattern>,也就是說一個Servlet可以有多個訪問路徑:
 

 <servlet-mapping>
    <servlet-name>xxx</servlet-name>
    <url-pattern>/helo1<url-pattern>
    <url-pattern>/hello2<url-pattern>
  </servlet-mapping>

  還可以在<url-pattern>中使用萬用字元,即“*”。

  •   <url-pattern>/*<url-pattern>:表示匹配任何路徑
  •   <url-pattern>/do/*<url-pattern>:表示匹配以/do開頭的任何路徑
  •    <url-pattern>*.do<url-pattern>:表示匹配任何以“.do”結尾的路徑

  注意:
  * 萬用字元要麼在開頭,要麼在結尾,不能在中間,例如:/*.do就是錯誤的使用。 如果不使用萬用字元,那麼<url-pattern>必須以“/”開頭,例如:<url-pattern>abc</url-pattern>就是錯誤的

===============================
===============================
===============================

8,ServletContext
  
  ServletContext是Servlet三大域物件之一
  ServletContext在伺服器啟動時建立,在伺服器關閉時銷燬,一個JavaWeb應用只建立一個ServletContext物件
  
1》. 它的功能分類:

  •    存取資料
  •   讀取web.xml中的應用初始化引數
  •   讀取應用資源

2》. 獲取ServletContext物件
  在HttpServlet中可以通過以下方法來獲取ServletContext物件

  •   ServletContext sc = this.getServletContext()
  •   ServletContext sc = this.getServletConfig().getServletContext()

3》. 存取資料
  因為在一個JavaWeb應用中,只有一個ServletContext物件,所以在ServletContext中儲存的資料可以共整個JavaWeb應用中的動態資源共享
  ServletContext是Servlet三大域物件之一,域物件內部有一個Map,用來儲存資料

  a,void setAttribute(String name, Object value):用來新增或替換ServletContext域資料

  •      servletContext.setAttribute("xxx", "XXX"),新增域資料
  •      servletContext.setAttribute("xxx", "XXXX"),覆蓋域資料,因為在域中已經存在了名為xxx的資料,所以這次就是覆蓋了

  b,Object getAttribute(String name):通過名稱來獲取域資料
  c, void removeAttribute(String name):通過名稱移除域資料
  d,Enumeration<String> getAttributeNames():獲取所有ServletContext域資料的名稱

4》. 讀取web.xml中配置的應用初始化引數

 

 <context-param>
    <param-name>p1</param-name>
    <param-value>v1</param-value>      
  </context-param>
  <context-param> 
    <param-name>p2</param-name>
    <param-value>v2</param-value>      
  </context-param>

  * servletContext.getInitParameter("p1"),返回v1
  * servletContext.getInitParameter("p2"),返回v2
  * servletContext.getInitParameterNames(),返回Enumeration<String>,包含p1和p2

5》. 獲取專案資源
  a,String getRealPath(String path):獲取資源的真實名稱
  String path = servletContext.getRealPath("/WEB-INF/a.jpg");
  返回值為/WEB-INF/a.jpg真實路徑,即磁碟路徑:C:/tomcat6/wabapps/hello/WEB-INF/a.jpg

  b, InputStream getResourceAsStream(String path):獲取資源的輸入流
  InputStream in = servletContext.getResourceAsStream("/WEB-INF/a.jpg");
  返回的是a.jpg的輸入流物件,可以從流中得到a.jpg的資料

  c, Set<String> getResourcePaths(String path):獲取指定目錄下的所有資源路徑
  Set<String> paths = servletContext.getResourcePaths("/WEB-INF");
  返回的Set中包含如下字串:
    > /WEB-INF/lib/
    > /WEB-INF/classes/
    > /WEB-INF/web.xml
    > /WEB-INF/a.jpg

===============================
===============================
===============================

9,獲取類路徑資源

  可以通過Class類的物件來獲取類路徑下的資源,對應JavaWeb應用的類路徑就是classes目錄下的資源
  例如:
  InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("a.jpg");
  獲取的是:/WEB-INF/classes/cn/itcast/servlet/a.jpg,即與MyServlet.class同目錄下的資源

  例如:
  InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("/a.jpg");
  獲取的是:/WEB-INF/classes/a.jpg,即類路徑的根目錄下的資源,類路徑的根目錄就是/classes目錄