Servlet以及單例設計模式


1.Servlet概述

a)Servlet,全城是Servlet Applet,服務器端小程序,是一個接口,定義了若干方法,要求所有的Servlet必須實現。

b)Servlet用於接收客戶端的請求,並對請求做出相應的相應。

c)Servlet中的方法:

>init:用於初始化Servlet;

>service:用於(執行)服務;

>destroy:在Servlet被銷毀前調用;

d)Servlet是一個接口,為了方便使用,官方提供了對應的實現類,關系如下:

Servlet:   -- GenericServlet(c):通用協議的Servlet;

                --HttpServlet(c):專門用於HTTP的Servlet;

2.定義Servlet並配置

2.1定義Servlet

測試時繼承了GenericServlet,實際使用時建議使用HttpServlet.

package com.bjsxt.servlet;

 

import java.io.IOException;

import javax.servlet.GenericServlet;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

public class FirstServlet extends GenericServlet{

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

                System.out.println("FirstServlet.service()");

                //響應信息

                res.getWriter().print("<h1>Hello Servlet!</h1>");

    }

}

2.2配置Servlet

在web.xml中配置Servlet,告訴Tomcat在客戶端訪問哪個路徑時,應該執行哪個Servlet.

<!-- 配置Servlet -->

<servlet>

               <servlet-name>FirstServlet</servlet-name>

               <servlet-class>com.bjsxt.servlet.FirstServlet</servlet-class>

               </servlet>

               <!-- 配置Servlet映射 -->

<servlet-mapping>

               <servlet-name>FirstServlet</servlet-name>

               <url-pattern>/abc</url-pattern>

               <!-- http://localhost:8080/0529_servlet_hello/abc -->

</servlet-mapping>

3.Servlet的執行過程(圖略)

a)客戶端通過瀏覽器輸入URL地址訪問Tomcat

b)Tomcat解析URL路徑

c)到當前項目的web.xml中匹配Servlet的映射路徑;

       ---如果匹配成功,則調用對應的Servlet的service方法;

       ---如果沒有匹配成功,則繼續到Tomcat的web.xml中匹配。

d)在Tomcat的web.xml中,提供了兩個Servlet,分別為DefaultServlet和JspServlet.

       ---JspServlet用於處理jsp

       ---DefaultServlet處理沒有匹配到其他Servlet的所有請求,用於加載靜態資源或404異常。

 4.Servlet配置詳解

a)web.xml的名稱不能改變,位置不能改變;

b)<servlet-name><servlet-class>要寫正確,必須要匹配;

c)關於<url-pattern>的幾種配置方式:

 

<servlet-mapping>

<servlet-name>FirstServlet</servlet-name>

<!-- 固定路徑, 必須以/開頭 -->

<url-pattern>/abc</url-pattern>

<!-- xxx結尾的路徑 -->

<url-pattern>*.sxt</url-pattern>

<!-- 訪問xxx下的路徑 -->

<url-pattern>/sxt/*</url-pattern>

<!-- 不可以使用如下的方式 -->

<!-- <url-pattern>/sxt/*.aaa</url-pattern> -->

<!-- 匹配所有的路徑包括jsp -->

<url-pattern>/*</url-pattern>

<!-- 匹配所有除了jsp之外的路徑 -->

<url-pattern>/</url-pattern>

</servlet-mapping>

 5.解決405異常

a)在HttpServlet中,service方法用於分發請求,例如:如果是get方式,就調用doGet方法;如果是post方式,就調用doPost方法。

b)而HttpServlet中的doPost方法和doGet方法沒有做什么事,就發送了一個405異常,因此,一旦執行到這兩個方法就會報405異常。

c)解決405異常的兩種方式

 ---子類重寫service方法:

public class DemoServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println("DemoServlet.service()");

}

}

 ---子類重寫doGet和doPost方法:

 

public class DemoServlet extends HttpServlet {

 

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println("DemoServlet.doGet()");

doPost(req, resp);

}

 

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println("DemoServlet.doPost()");

}

}

 6.單例設計模式

a)設計模式是解決特定問題的最佳方案。

b)單例,單個對象,在對象的使用過程中,永遠都只創建一個對象;

c)餓漢式單例,類加載時就創建對象,由於靜態成員變量只被加載一次,所以保證了對象之創建一次;

 

package com.bjsxt.singleton;

 

/**

 * 餓漢式單例

 * 不管這個對象是否被使用, 先被創建

 * @author Administrator

 *

 */

public class HungrySingleton {

 

private static HungrySingleton instance = new HungrySingleton();

 

private HungrySingleton() {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("創建對象[餓漢式]");

}

 

/**

 * 靜態方法, 用於給其他類提供對象

 *

 * @return

 */

public static HungrySingleton getInstance() {

return instance;

}

}

 d)懶漢式單例,在需要的時候才創建對象,多線程時不安全,需要使用雙重檢查機制保證線程安全;

package com.bjsxt.singleton;

 

/**

 * 懶漢式單例

 *

 * @author Administrator

 *

 */

public class LazySingleton {

 

private static LazySingleton instance;

 

private LazySingleton() {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("創建對象[懶漢式]");

}

 

public static LazySingleton getInstance() {

if (instance == null) {

synchronized (LazySingleton.class) {

// Double Check, 雙重檢查

if (instance == null) {

instance = new LazySingleton();

}

}

}

return instance;

}

}

7.餓漢式單例和懶漢式單例的比較

a)餓漢式:

  >代碼非常簡單。

 >類加載時及創建對象,該對象可能並不會被使用。

 >多線程下也可以保證單例的實現,沒有問題。

 >省去了判斷,效率較高;

b)懶漢式:

  >代碼較為復雜

  >類加載時不會創建對象,需要時才創建,不會創建多余的對象。

  >多線程時可能會有線程安全問題,需要進行Double Check。

  >需要很多判斷,效率較低;

8.Servlet的生命周期

a)Servlet是單實例,多線程的

b)生命周期階段

   ----創建:構造器只創建一次;

   ----初始化:innit,只初始化一次;

   ---執行:service,累一次請求執行一次;

   ---銷毀:destroy,項目卸載或服務關閉時,Servlet被銷毀,銷毀前會由服務器調用destriy方法;

c)默認情況下,Servlet是懶漢式單例,對象是在第一次請求時被創建的。

d) 如果希望Servlet在服務器啟動時就創建, 可以在<servlet>標簽下通過<load-on-startup>標簽進行指定. 該標簽需要配置一個整數:

  • 負整數: 和不配置一樣, 表示第一次請求時創建和初始化.
  • 0和正整數: 表示服務器啟動時就創建和初始化, 數字越小, 被加載的優先級越高. 如果數字相同加載順序由服務器決定.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM