深入理解servlet

總結:

一、servlet的生命週期

Servlet程序的生命週期由tomcat服務器控制的!!!servlet的四個重要的方法是自身的無參構造函數、init方法、service(或者是doGet、doPost方法,其中三個功能我測試的時候是一樣的,三者有你沒我,都有隻會執行service的方法)、destory方法(當servlet重啓或者tomcat關閉的時候會運行)

二、servlet是懶加載的,只有請求到來時,纔會反射生成對象,執行業務邏輯

三、servlet是單實例(單例)多線程(這個可以從它的init方法只會執行一遍可以看出),要注意線程安全型的問題

四、域對象:作用範圍在整個web應用中有效!!!

servlet中的所有域對象:

HttpServletRequet 域對象

ServletContext域對象

HttpSession 域對象

PageContext域對象

 

 

 

深入理解Servlet

課程目標

動態資源與靜態資源區別

1. servlet三及相關接口簡介

2. servet 執行過程

3. servlet路徑映射

4. servlet生命週期(重點)   --理解(重點)

5. Servlet自動加載 

6. Servlet線程安全 

7. Servlet相關接口詳解

8. ServletContext對象     --知識點

Web項目結構

 

|- WebRoot :   web應用的根目錄

|- 靜態資源(html+css+js+image+vedio)STATIC
|- WEB-INF : 固定寫法。

|-classes: (可選)固定寫法。存放class字節碼文件

|-lib: (可選)固定寫法。存放jar包文件。

|-web.xml    

 

注意:

1)WEB-INF目錄裏面的資源不能通過瀏覽器直接訪問

2)如果希望訪問到WEB-INF裏面的資源,就必須把資源配置到一個叫web.xml的文件中。

 

 

練習:

1)在webapps下建立一個mybbs目錄

2)創建兩個文件

2.1 index.html  裏面隨便寫內容 ,有超鏈接-連接到test.html

2.2 test.html   裏面隨便寫

3)通過瀏覽器訪問到。

 

手動開發動態資源

2.1靜態資源和動態資源的區別

靜態資源: 當用戶多次訪問這個資源,資源的源代碼永遠不會改變的資源。

動態資源:當用戶多次訪問這個資源,資源的源代碼可能會發送改變。

2.2源的開發技術

Servlet : 用java語言來編寫動態資源的開發技術。

 

Servlet特點:

1)普通的java類,繼承HttpServlet類,覆蓋doGet方法

2)Servlet類只能交給tomcat服務器運行!!!!(開發者自己不能運行!!!)

 

Servlet手動編寫步驟:

1)編寫一個servlet程序,繼承HttpServlet

 

/**

 * 第一個servlet程序

 * @author APPle

 *

 */

public class HelloServlet extends HttpServlet{

 

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

//解決中文亂碼問題

    resp.setCharacterEncoding("utf-8");// 內容編碼,防止出現中文亂碼

resp.setContentType("text/html;charset=utf-8"); //向瀏覽器輸出內容

resp.getWriter().write("這是第一個servlet程序。當前時間爲:"+new Date());

}

}

 

2)找到HelloServlet類的class字節碼,然後把拷貝到tomcat的一個web應用中WEB-INF/classes目錄下。

3)在當前web應用下的web.xml文件配置Servlet。

 

<!-- 配置一個servlet程序 -->

<servlet>

<!-- servlet的內部名稱 ,可以自定義-->

<servlet-name>HelloServlet</servlet-name>

<!-- servlet類名: 包名+簡單類名-->

<servlet-class>com.itmayiedu.HelloServlet</servlet-class>

</servlet>

 

<servlet-mapping>

<!-- servlet的內部名稱,和上面的名稱保持一致!!!-->

<servlet-name>HelloServlet</servlet-name>

<!-- servlet的訪問名稱: /名稱 -->

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

</servlet-mapping>

 

4)啓動tomcat服務器,運行訪問

訪問servlet:  http://localhost:8080/myweb/ hello

、工具開發動態資源

1)創建web project (javaweb工程)

2)在WebRoot下建立靜態資源文件,

3)在src下建立動態資源文件

  3.1 new -> Servlet( servlet的代碼生成器)

  3.2 寫pacakge  -> class名 -> 修改mapping  url

4)關聯tomcat服務器

4.1 window-> Preferences - > MyEcplise -> servers -> Tomcat 6.x (注意一定要enable)

 

5)部署web project應用。(拷貝web應用到tomcat的webapps目錄下)

6)啓動tomcat服務器

7)訪問servlet

http://localhost:8081/myWeb /hello

 

 

3.1 如何開發一個Servlet

1.1 步驟:

1)編寫java類,繼承HttpServlet類

2)重新doGet和doPost方法

3)Servlet程序交給tomcat服務器運行!!

3.1 servlet程序的class碼拷貝到WEB-INF/classes目錄

3.2 在web.xml文件中進行配置

 

<!-- 配置一個servlet -->

  <!-- servlet的配置 -->

  <servlet>

   <!-- servlet的內部名稱,自定義。儘量有意義 -->

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

   <!-- servlet的類全名: 包名+簡單類名 -->

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

  </servlet>

  

  

  <!-- servlet的映射配置 -->

  <servlet-mapping>

   <!-- servlet的內部名稱,一定要和上面的內部名稱保持一致!! -->

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

   <!-- servlet的映射路徑(訪問servlet的名稱) -->

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

  </servlet-mapping>

 

問題:訪問次URL:  http://localhost:8080/myweb /first  

 

前提: tomcat服務器啓動時,首先加載webapps中的每個web應用的web.xml配置文件。

http://: http協議

localhost: 到本地的hosts文件中查找是否存在該域名對應的IP地址

127.0.0.1

8080:    找到tomcat服務器

/day10     在tomcat的webapps目錄下找 day10的目錄

/first    資源名稱。

1)在myweb的web.xml中查找是否有匹配的url-pattern的內容(/first)

2)如果找到匹配的url-pattern,則使用當前servlet-name的名稱到web.xml文件中查詢是否相同名稱的servlet配置

3)如果找到,則取出對應的servlet配置信息中的servlet-class內容:

字符串: com.itmayiedu.a_servlet.FirstServlet

 

通過反射:

a)構造FirstServlet的對象

b)然後調用FirstServlet裏面的方法

3.3 Servlet 註解版本

Servlet3.0以上使用 註解自動映射@webServlet.

3.4 Sevlet的生命週期(重點)

4.1 引入

Servlet的生命週期: servlet類對象什麼時候創建,什麼時候調用什麼方法,什麼時候銷燬。

 

以前的對象: new Student(); stu.study();   stu=null;

 

Servlet程序的生命週期由tomcat服務器控制的!!!!

 

4.2 Servlet重要的四個生命週期方法

構造方法: 創建servlet對象的時候調用。默認情況下,第一次訪問servlet的時候創建servlet對象 只調用1次。證明servlet對象在tomcat是單實例的。

init方法: 創建完servlet對象的時候調用。只調用1次。

service方法: 每次發出請求時調用。調用n次。

destroy方法: 銷燬servlet對象的時候調用。停止服務器或者重新部署web應用時銷燬servlet對象。

只調用1次。

 

4.3 僞代碼演示servlet的生命週期

Tomtcat內部代碼運行:

1)通過映射找到到servlet-class的內容,字符串: com.itmayiedu.a_servlet.FirstServlet

2)通過反射構造FirstServlet對象

2.1 得到字節碼對象

Class clazz = class.forName("com.itmayiedu.a_servlet.FirstServlet");

2.2 調用無參數的構造方法來構造對象

Object obj = clazz.newInstance();     ---1.servlet的構造方法被調用

3)創建ServletConfig對象,通過反射調用init方法

3.1 得到方法對象

Method m = clazz.getDeclareMethod("init",ServletConfig.class);

3.2 調用方法

m.invoke(obj,config);             --2.servlet的init方法被調用

4)創建request,response對象,通過反射調用service方法

4.1 得到方法對象

Methodm m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);

4.2 調用方法

m.invoke(obj,request,response);  --3.servlet的service方法被調用

5)當tomcat服務器停止或web應用重新部署,通過反射調用destroy方法

5.1 得到方法對象

Method m = clazz.getDeclareMethod("destroy",null);

5.2 調用方法

m.invoke(obj,null);            --4.servlet的destroy方法被調用

1、執行順序:

 先執行自己的無參構造函數

然後init方法

執行service或者doGet方法(每次請求到來時都會執行這個方法,service方法重寫的時候,doGEt或者doPost 方法不會執行)

最後重啓的時候執行destrory方法

 

4.4 用時序圖來演示servlet的生命週期

uploading.4e448015.gif轉存失敗重新上傳取消

3.5 Servlet的自動加載

默認情況下,第一次訪問servlet的時候創建servlet對象。如果servlet的構造方法或init方法中執行了比較多的邏輯代碼,那麼導致用戶第一次訪問sevrlet的時候比較慢。

 

改變servlet創建對象的時機: 提前到加載web應用的時候!!!

 

在servlet的配置信息中,加上一個<load-on-startup>即可!!

 

<servlet>

    <servlet-name>LifeDemo</servlet-name>

    <servlet-class>com.itmayiedu.life.LifeDemo</servlet-class>

    <!-- 讓servlet對象自動加載 -->

    <load-on-startup>1</load-on-startup>  注意: 整數值越大,創建優先級越低!!

  </servlet>

 

3.6 Servlet的多線程併發問題

注意: servlet對象在tomcat服務器是單實例多線程的,要注意線程安全型的問題。

 

因爲servlet是多線程的,所以當多個servlet的線程同時訪問了servlet的共享數據,如成員變量,可能會引發線程安全問題。

 

解決辦法:

1)把使用到共享數據的代碼塊進行同步(使用synchronized關鍵字進行同步)

2)建議在servlet類中儘量不要使用成員變量。如果確實要使用成員,必須同步。而且儘量縮小同步代碼塊的範圍。(哪裏使用到了成員變量,就同步哪裏!!),以避免因爲同步而導致併發效率降低。

 

Servlet學習:

 HttpServletRequest  請求對象:獲取請求信息

 HttpServletResponse 響應對象: 設置響應對象

 ServletConfig對象    servlet配置對象

 ServletContext對象; servlet的上下文對象

線程安全代碼:

package com.servlet;

 

import java.io.IOException;

import java.util.Date;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

/**

 *

 * @classDesc: 功能描述:(線程安全演示)

 * @author: 餘勝軍

 * @createTime: 2017年8月31日 下午11:47:20

 * @version: v1.0

 * @copyright:上海每特教育科技有限公司

 */

public class ServetlDemo4 extends HttpServlet {

private int i = 1;

 

@Override

public void init() throws ServletException {

System.out.println("ServetlDemo4...init()");

}

 

@Override

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

 

// 設置編碼格式

// resp.setContentType("text/html;charset=utf-8");

resp.setCharacterEncoding("utf-8");// 內容編碼,防止出現中文亂碼

resp.setContentType("text/html;charset=utf-8");

synchronized (ServetlDemo4.class) {

// 向瀏覽器輸出內容

resp.getWriter().write("這是第" + i + "次訪問...");

try {

Thread.sleep(5000);

} catch (Exception e) {

// TODO: handle exception

}

 

i++;

}

 

}

 

@Override

public void destroy() {

System.out.println("ServetlDemo4...destroy()");

 

}

 

}

 

 ServletContext對象

4.1得到web應用路徑

java.lang.String getContextPath()  用在請求重定向的資源名稱中

4.2域對象有關的方法

域對象:作用是用於保存數據,獲取數據。可以在不同的動態資源之間共享數據

 

案例:   

Servlet1                   Servlet2

        name=eric                     

response.sendRedirect("/Servlet2?name=eric")             String request.getParameter("name");

保存到域對象中            從域對象獲取

Student                  

方案1: 可以通過傳遞參數的形式,共享數據。侷限:只能傳遞字符串類型。

方案2: 可以使用域對象共享數據,好處:可以共享任何類型的數據!!!!!

 

ServletContext就是一個域對象!!!!

 

保存數據:void setAttribute(java.lang.String name, java.lang.Object object)

獲取數據: java.lang.Object getAttribute(java.lang.String name)  

刪除數據: void removeAttribute(java.lang.String name)  

 

ServletContext域對象:作用範圍在整個web應用中有效!!!

 

所有域對象:

HttpServletRequet 域對象

ServletContext域對象

HttpSession 域對象

PageContext域對象

 

4.3轉發與重定

 RequestDispatcher getRequestDispatcher(java.lang.String path)

 

1)轉發

 a)地址欄不會改變

 b)轉發只能轉發到當前web應用內的資源

c)可以在轉發過程中,可以把數據保存到request域對象中

 

2)重定向

a)地址欄會改變,變成重定向到地址。

b)重定向可以跳轉到當前web應用,或其他web應用,甚至是外部域名網站。

c)不能再重定向的過程,把數據保存到request中。

                自定義重定向:

                  

response.setStatus(302); 

response.setHeader("Location","OtherServlet"); 

 

 

結論: 如果要使用request域對象進行數據共享,只能用轉發技術!!!

 

 

總結:

Servlet編程:

Servlet生命週期(重點)

其他都是應用的東西(敲代碼練習)

 

   第一個熟悉作用域區別

第二個目標就是熟悉重定向底層原理。

 

.

 

 

 

代碼:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章