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可以使用通配符

通配符有兩種格式:

  1. *.擴展名
  2. 正斜杠(/)開頭并以“/*”結尾。

匹配所有

匹配擴展名為.jsp的

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

  1. 看誰的匹配度高,誰就被選擇
  2. *.擴展名的優先級最低

Servlet映射的URL可以使用通配符和Servlet可以被映射到多個URL上的作用:

  1. 隱藏網站是用什么編程語言寫的【.php,.net,.asp實際上訪問的都是同一個資源】
  2. 用特定的后綴聲明版權【公司縮寫】
<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共享資源的時候就會出現線程安全問題

原則:

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

load-on-startup

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

作用:

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

在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有什么用?

  1. ServletContext既然代表著當前web站點,那么所有Servlet都共享著一個ServletContext對象,所以Servlet之間可以通過ServletContext實現通訊
  2. ServletConfig獲取的是配置的是單個Servlet的參數信息,ServletContext可以獲取的是配置整個web站點的參數信息
  3. 利用ServletContext讀取web站點的資源文件
  4. 實現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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253559.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253559.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253559.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue響應式原理

vue響應式原理 initState new Vue() > _init() > initState: function initState (vm: Component) {vm._watchers []const opts vm.$optionsif (opts.props) initProps(vm, opts.props)if (opts.methods) initMethods(vm, opts.methods)if (opts.data) {initData(vm)} …

Oracle數據庫管理與開發pdf

下載地址&#xff1a;網盤下載基本介紹編輯內容簡介Oracle是一個適合于大中型企事業的數據庫管理系統&#xff0c;在銀行、電信、移動通信、航空、保險、金融、氣象、鐵路、跨國公司和電子商務等諸多領域得到了廣泛的應用。據統計&#xff0c;在所有數據庫管理系統中&#xff0…

DVS/DVR區別

一、DVS &#xff08;Digital Video Server&#xff09;網絡視頻服務器的簡稱。DVS(網絡視頻服務器)的原理網絡視頻服務器主要實現模擬視音頻信號的IP 化。經數字化的視音頻信號MPEG-4 視頻壓縮算法和G.729/ADPCM 音頻壓縮算法進行壓縮編碼&#xff0c;然后通過IP 網將低碼率的…

自動對焦方法學習

實現自動對焦的方法有很多種,可以根據不同的工作原理,將自動對焦技術分成不同種類。 按照系統是否自帶信號發射系統,可以分為主動式與被動式兩種類型。 主動式對焦方法是由成像系統中的發射裝置發出信號,然后再由接收裝置接收從被攝景物所反射回來的反饋信號并利用通過計算…

微粒化運營:升級內容產業消費體驗(附視頻版)

那些最受歡迎的內容平臺做對了什么&#xff1f; Facebook和Google是全球互聯網廣告產業中最早開始微粒化運營的代表&#xff0c;Google的互聯網精準廣告的思路與微粒化運營是完全相同的&#xff0c;這兩家公司也因此獲得了全球超過20%的互聯網廣告的收入。 以Facebook為例&…

mycat讀寫分離

只需要讀寫分離的功能&#xff0c;分庫分表的都不需要。 涉及到的配置文件&#xff1a; 1.conf/server.xml 主要配置的是mycat的用戶名和密碼&#xff0c;mycat的用戶名和密碼和mysql的用戶名密碼是分開的&#xff0c;應用連接mycat就用這個用戶名和密碼。 <?xml version&q…

chisel快速入門(一)

一、概述 Chisel&#xff08;Constructing Hardware In a Scala Embedded Language&#xff09;是一種嵌入在高級編程語言Scala的硬件構建語言。Chisel實際上只是一些特殊的類定義&#xff0c;預定義對象的集合&#xff0c;使用Scala的用法&#xff0c;所以在寫Chisel程序時實際…

DVS/DVR常見的監控名詞

英文名詞 說明BNC 全稱Bayonet Nut Connector&#xff0c;一種用于同軸電纜的連接器DHCP 動態主機配置協議&#xff0c;用于動態地指派配置信息DNS 域名系統&#xff0c;以用戶友好的方式將名字轉換為…

導出數據生成excel

前臺&#xff1a; <asp:Button ID"btnMoney" runat"server" Text"經費使用總結表" CssClass"admin_cx marginleft" Height"25" OnClick"btnMoney_Click" /> 后臺&#xff1a; protected void btnMoney_Cli…

U盤基本處理,U盤與移動固態硬盤

一、辨別 USB2.0 和 USB3.0 1、從USB外觀上來看&#xff0c;USB2.0通常是白色或黑色&#xff0c;而USB3.0則改觀為“高大上”的藍色接口。 目前&#xff0c;部分筆記本電腦USB接口&#xff0c;已同時提供對USB2.0及USB3.0的支持&#xff0c;我們可以通過接口顏色來區別。 2、從…

UWP_小說在線閱讀器:功能要求與技術要求

注&#xff1a;2017年2月23日正式提上日程 學了WP開發也有一年了&#xff0c;也沒做過什么軟件的。17年進發UWP&#xff0c;鍛煉自己一下。做一個開源的小說閱讀器吧。 既然開發一個軟件。所以要設計一下吧。 功能要求&#xff1a; 可能要用到的技術&#xff0c;這個嗎&#xf…

chisel快速入門(二)

上一篇見此&#xff1a; chisel快速入門&#xff08;一&#xff09;_滄海一升的博客-CSDN博客簡單介紹了chisel&#xff0c;使硬件開發者能快速上手chisel。https://blog.csdn.net/qq_21842097/article/details/121415341 十、運行和測試 現在我們已經定義了模塊&#xff0c;…

【WPF】設置TextBox內容為空時的提示文字

原文:【WPF】設置TextBox內容為空時的提示文字<TextBox Width"150" Margin"5"><TextBox.Resources><VisualBrush x:Key"HintText" TileMode"None" Opacity"0.5" Stretch"None" AlignmentX"Le…

視頻矩陣

視頻矩陣&#xff0c;就將視頻圖像從任意一個輸入通道切換到任意一個輸出通道顯示。一般來講,一個MN矩陣&#xff1a;表示它可以同時支持M路圖像輸入和N路圖像輸出。即任意的一個輸入和任意的一個輸出。 視頻矩陣 - 基本功能和要求 一個矩陣系統通常還應該包括以下基本功能&…

Spring 教程03

spring-3 1. Xml<!-- \src\applicationContext-xml.xml --> <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance…

讀書筆記之《The Art of Readable Code》Part 2

如何寫好流程控制語句(if-else/switch/while/for)使得代碼更可讀些&#xff1f;(chap 7)* 提高條件語句的可讀性(if語句, 或者bool型summary變量) if (length > 10) // Good if (10 < length) // Badwhile (bytes_received < bytes_expected) // Good while (b…

chisel快速入門(三)

前一篇見此&#xff1a; chisel快速入門&#xff08;二&#xff09;_滄海一升的博客-CSDN博客簡單介紹了chisel&#xff0c;使硬件開發者能快速上手chisel。https://blog.csdn.net/qq_21842097/article/details/121418806 十四、模塊的功能創建 制造用于模塊構造的功能接口也…

Redis作者攤上事了:多人要求修改Redis主從復制術語master/slave

作者 | ANTIREZ、小智近日&#xff0c;Redis 作者在 GitHub 上發起了一個“用其他詞匯代替 Redis 的主從復制術語”的 issue。有人認為 Redis 中的術語 master/slave &#xff08;主人 / 奴隸&#xff09;冒犯到了別人&#xff0c;要求 Redis 作者 ANTIREZ 修改這個術語&#x…

????C字符串數組賦值

C字符數組賦值 舉例如下&#xff1a; char a[10]; 1、定義的時候直接用字符串賦值 char a[10]"hello"; 注意&#xff1a;不能先定義再給它賦值&#xff0c;如 char a[10]; a[10]"hello"; 這樣是錯誤的&#xff01; 2、對數組中字符逐個賦值 char a[10]{h…

WP8.1使用HttpClient類

Uri uri new Uri("http://www.cnsos.net/weburl/index.htm", UriKind.Absolute); HttpClient myClient new HttpClient(); string result await myClient.GetStringAsync(uri); await new MessageDialog(result).ShowAsync(); 轉載于:https://www.cnblogs.com/wzw…