日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】

發布時間:2023/12/13 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Servlet的調用圖

前面我們已經學過了Servlet的生命周期了,我們根據Servlet的生命周期畫出Servlet的調用圖加深理解

Servlet的細節

一個已經注冊的Servlet可以被多次映射

同一個Servlet可以被映射到多個URL上。

<servlet><servlet-name>Demo1</servlet-name><servlet-class>zhongfucheng.web.Demo1</servlet-class></servlet><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>/Demo1</url-pattern></servlet-mapping><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>/ouzicheng</url-pattern></servlet-mapping>

無論我訪問的是http://localhost:8080/Demo1還是http://localhost:8080/ouzicheng。我訪問的都是Demo1。

Servlet映射的URL可以使用通配符

通配符有兩種格式:

  • *.擴展名
  • 正斜杠(/)開頭并以“/*”結尾。
  • 匹配所有

    匹配擴展名為.jsp的

    如果.擴展名和正斜杠(/)開頭并以“/”結尾兩種通配符同時出現,匹配的是哪一個呢?

  • 看誰的匹配度高,誰就被選擇
  • *.擴展名的優先級最低
  • Servlet映射的URL可以使用通配符和Servlet可以被映射到多個URL上的作用:

  • 隱藏網站是用什么編程語言寫的【.php,.net,.asp實際上訪問的都是同一個資源】
  • 用特定的后綴聲明版權【公司縮寫】
  • <servlet><servlet-name>Demo1</servlet-name><servlet-class>zhongfucheng.web.Demo1</servlet-class></servlet><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>*.jsp</url-pattern></servlet-mapping><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>*.net</url-pattern></servlet-mapping><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>*.asp</url-pattern></servlet-mapping><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>*.php</url-pattern></servlet-mapping>

    Servlet是單例的

    為什么Servlet是單例的

    瀏覽器多次對Servlet的請求,一般情況下,服務器只創建一個Servlet對象,也就是說,Servlet對象一旦創建了,就會駐留在內存中,為后續的請求做服務,直到服務器關閉

    每次訪問請求對象和響應對象都是新的

    對于每次訪問請求,Servlet引擎都會創建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,然后將這兩個對象作為參數傳遞給它調用的Servlet的service()方法service方法再根據請求方式分別調用doXXX方法

    線程安全問題

    當多個用戶訪問Servlet的時候,服務器會為每個用戶創建一個線程當多個用戶并發訪問Servlet共享資源的時候就會出現線程安全問題

    原則:

  • 如果一個變量需要多個用戶共享,則應當在訪問該變量的時候,加同步機制synchronized (對象){}
  • 如果一個變量不需要共享,則直接在 doGet() 或者 doPost()定義.這樣不會存在線程安全問題

  • load-on-startup

    如果在元素中配置了一個元素,那么WEB應用程序在啟動時,就會裝載并創建Servlet的實例對象、以及調用Servlet實例對象的init()方法

    作用:

  • 為web應用寫一個InitServlet,這個servlet配置為啟動時裝載,為整個web應用創建必要的數據庫表和數據
  • 完成一些定時的任務【定時寫日志,定時備份數據】

  • 在web訪問任何資源都是在訪問Servlet

    當你啟動Tomcat,你在網址上輸入http://localhost:8080。為什么會出現Tomcat小貓的頁面?

    這是由缺省Servlet為你服務的

    • 我們先看一下web.xml文件中的配置,web.xml文件配置了一個缺省Servlet
    <servlet><servlet-name>default</servlet-name><servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>listings</param-name><param-value>false</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>default</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
    • 什么叫做缺省Servlet?凡是在web.xml文件中找不到匹配的元素的URL,它們的訪問請求都將交給缺省Servlet處理,也就是說,缺省Servlet用于處理所有其他Servlet都不處理的訪問請求
    • 既然我說了在web訪問任何資源都是在訪問Servlet,那么我訪問靜態資源【本地圖片,本地HTML文件】也是在訪問這個缺省Servlet【DefaultServlet】
    • 證實一下:當我沒有手工配置缺省Servlet的時候,訪問本地圖片是可以訪問得到的

    • 現在我自己配置一個缺省Servlet,Demo1就是我手工配置的缺省Servlet,覆蓋掉web.xml配置的缺省Servlet
    <servlet><servlet-name>Demo1</servlet-name><servlet-class>zhongfucheng.web.Demo1</servlet-class></servlet><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
    • 下面我繼續訪問一下剛才的圖片,此時輸出的是Demo1這個Servlet寫上的內容了

    • 總結:無論在web中訪問什么資源【包括JSP】,都是在訪問Servlet。沒有手工配置缺省Servlet的時候,你訪問靜態圖片,靜態網頁,缺省Servlet會在你web站點中尋找該圖片或網頁,如果有就返回給瀏覽器,沒有就報404錯誤

    ServletConfig對象

    ServletConfig對象有什么用?

    通過此對象可以讀取web.xml中配置的初始化參數。

    現在問題來了,為什么我們要把參數信息放到web.xml文件中呢?我們可以直接在程序中都可以定義參數信息,搞到web.xml文件中又有什么好處呢

    好處就是:能夠讓你的程序更加靈活【更換需求,更改配置文件web.xml即可,程序代碼不用改】

    獲取web.xml文件配置的參數信息

    • 為Demo1這個Servlet配置一個參數,參數名是name,值是zhongfucheng
    <servlet><servlet-name>Demo1</servlet-name><servlet-class>zhongfucheng.web.Demo1</servlet-class><init-param><param-name>name</param-name><param-value>zhongfucheng</param-value></init-param></servlet><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>/Demo1</url-pattern></servlet-mapping>
    • 在Servlet中獲取ServletConfig對象,通過ServletConfig對象獲取在web.xml文件配置的參數

    ServletContext對象

    什么是ServletContext對象?

    當Tomcat啟動的時候,就會創建一個ServletContext對象。它代表著當前web站點

    ServletContext有什么用?

  • ServletContext既然代表著當前web站點,那么所有Servlet都共享著一個ServletContext對象,所以Servlet之間可以通過ServletContext實現通訊
  • ServletConfig獲取的是配置的是單個Servlet的參數信息,ServletContext可以獲取的是配置整個web站點的參數信息
  • 利用ServletContext讀取web站點的資源文件
  • 實現Servlet的轉發【用ServletContext轉發不多,主要用request轉發】
  • Servlet之間實現通訊

    ServletContext對象可以被稱之為域對象

    到這里可能有一個疑問,域對象是什么呢?其實域對象可以簡單理解成一個容器【類似于Map集合】

    實現Servlet之間通訊就要用到ServletContext的setAttribute(String name,Object obj)方法
    第一個參數是關鍵字,第二個參數是你要存儲的對象

    • 這是Demo2的代碼
    //獲取到ServletContext對象ServletContext servletContext = this.getServletContext();String value = "zhongfucheng";//MyName作為關鍵字,value作為值存進 域對象【類型于Map集合】servletContext.setAttribute("MyName", value);
    • 這是Demo3的代碼
    //獲取ServletContext對象ServletContext servletContext = this.getServletContext();//通過關鍵字獲取存儲在域對象的值String value = (String) servletContext.getAttribute("MyName");System.out.println(value);
    • 訪問Demo3可以獲取Demo2存儲的信息,從而實現多個Servlet之間通訊


    獲取web站點配置的信息

    如果我想要讓所有的Servlet都能夠獲取到連接數據庫的信息,不可能在web.xml文件中每個Servlet中都配置一下,這樣代碼量太大了!并且會顯得非常啰嗦冗余。

    • web.xml文件支持對整個站點進行配置參數信息所有Servlet都可以取到該參數信息
    <context-param><param-name>name</param-name><param-value>zhongfucheng</param-value></context-param>
    • Demo4代碼
    //獲取到ServletContext對象ServletContext servletContext = this.getServletContext();//通過名稱獲取值String value = servletContext.getInitParameter("name");System.out.println(value);

    • 試一下Demo3是否能拿到,相同的代碼
    //獲取到ServletContext對象ServletContext servletContext = this.getServletContext();//通過名稱獲取值String value = servletContext.getInitParameter("name");System.out.println(value);


    讀取資源文件

    第一種方式:

    • 現在我要通過Servlet111讀取1.png圖片

    • 按我們以前的方式,代碼應該是這樣的。
    FileInputStream fileInputStream = new FileInputStream("1.png");System.out.println(fileInputStream);
    • 當我們訪問的時候,卻出錯了!說找不到1.png文件

    • 這是為什么呢?我們以前讀取文件的時候,如果程序和文件在同一包名,可以直接通過文件名稱獲取得到的!,原因很簡單,以前我們寫的程序都是通過JVM來運行的,而現在,我們是通過Tomcat來運行的
    • 根據web的目錄規范,Servlet編譯后的class文件是存放在WEB-INF\classes文件夾中的

    • 看到這里,我們知道了要進入classes目錄中讀取文件,所以我們將代碼改成以下方式
    FileInputStream fileInputStream = new FileInputStream("D:\\zhongfucheng\\web\\WEB-INF\\classes\\zhongfucheng\\web\\1.png");System.out.println(fileInputStream);
    • 再去讀取時,就發現可以獲取到文件了。
    • 但是現在問題又來了,我讀取文件的時候都要寫上絕對路徑,這樣太不靈活了。試想一下,如果我將該讀取文件的模塊移到其他的web站點上我的代碼就又要修改了【因為web站點的名字不一樣】
    • 我們通過ServletContext讀取就可以避免修改代碼的情況,因為ServletContext對象是根據當前web站點而生成的
    • 代碼如下所示:
    //獲取到ServletContext對象ServletContext servletContext = this.getServletContext();//調用ServletContext方法獲取到讀取文件的流InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/classes/zhongfucheng/web/1.png");


    第二種方式:

    • 如果我的文件放在web目錄下,那么就簡單得多了!,直接通過文件名稱就能獲取

    • 代碼如下所示
    //獲取到ServletContext對象ServletContext servletContext = this.getServletContext();//調用ServletContext方法獲取到讀取文件的流InputStream inputStream = servletContext.getResourceAsStream("2.png");


    第三種方式:

    通過類裝載器讀取資源文件

    • 我的文件放在了src目錄下【也叫做類目錄】

    • 代碼如下所示
    //獲取到類裝載器ClassLoader classLoader = Servlet111.class.getClassLoader();//通過類裝載器獲取到讀取文件流InputStream inputStream = classLoader.getResourceAsStream("3.png");

    • 我的文件放在了src目錄下的包下

    • 代碼如下,添加包名路徑即可。
    //獲取到類裝載器ClassLoader classLoader = Servlet111.class.getClassLoader();//通過類裝載器獲取到讀取文件流InputStream inputStream = classLoader.getResourceAsStream("/zhongfucheng/web/1.png");

    原則:如果文件太大,就不能用類裝載器的方式去讀取,會導致內存溢出


    轉載于:https://www.cnblogs.com/zhong-fucheng/p/7203059.html

    總結

    以上是生活随笔為你收集整理的Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。