成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Servlet第二篇【Servlet調(diào)用圖、Servlet細(xì)節(jié)、ServletConfig、Serv

luck / 3265人閱讀

摘要:無論我訪問的是還是。映射的可以使用通配符通配符有兩種格式擴(kuò)展名正斜杠開頭并以結(jié)尾。當(dāng)多個(gè)用戶并發(fā)訪問共享資源的時(shí)候就會(huì)出現(xiàn)線程安全問題。

Servlet的調(diào)用圖

前面我們已經(jīng)學(xué)過了Servlet的生命周期了,我們根據(jù)Servlet的生命周期畫出Servlet的調(diào)用圖加深理解

Servlet的細(xì)節(jié) 一個(gè)已經(jīng)注冊(cè)的Servlet可以被多次映射

同一個(gè)Servlet可以被映射到多個(gè)URL上。

        
            Demo1
            zhongfucheng.web.Demo1
        
        
            Demo1
            /Demo1
        
        
            Demo1
            /ouzicheng
        

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

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

通配符有兩種格式:

*.擴(kuò)展名

正斜杠(/)開頭并以“/*”結(jié)尾。

匹配所有

匹配擴(kuò)展名為.jsp的

如果.擴(kuò)展名和正斜杠(/)開頭并以“/”結(jié)尾兩種通配符同時(shí)出現(xiàn),匹配的是哪一個(gè)呢?

看誰的匹配度高,誰就被選擇

*.擴(kuò)展名的優(yōu)先級(jí)最低

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

隱藏網(wǎng)站是用什么編程語言寫的【.php,.net,.asp實(shí)際上訪問的都是同一個(gè)資源】

用特定的后綴聲明版權(quán)【公司縮寫】

         
            Demo1
            zhongfucheng.web.Demo1
        
        
            Demo1
            *.jsp
        
        
            Demo1
            *.net
        
        
            Demo1
            *.asp
        
        
            Demo1
            *.php
        


Servlet是單例的 為什么Servlet是單例的

瀏覽器多次對(duì)Servlet的請(qǐng)求,一般情況下,服務(wù)器只創(chuàng)建一個(gè)Servlet對(duì)象,也就是說,Servlet對(duì)象一旦創(chuàng)建了,就會(huì)駐留在內(nèi)存中,為后續(xù)的請(qǐng)求做服務(wù),直到服務(wù)器關(guān)閉

每次訪問請(qǐng)求對(duì)象和響應(yīng)對(duì)象都是新的

對(duì)于每次訪問請(qǐng)求,Servlet引擎都會(huì)創(chuàng)建一個(gè)新的HttpServletRequest請(qǐng)求對(duì)象和一個(gè)新的HttpServletResponse響應(yīng)對(duì)象,然后將這兩個(gè)對(duì)象作為參數(shù)傳遞給它調(diào)用的Servlet的service()方法,service方法再根據(jù)請(qǐng)求方式分別調(diào)用doXXX方法。

線程安全問題

當(dāng)多個(gè)用戶訪問Servlet的時(shí)候,服務(wù)器會(huì)為每個(gè)用戶創(chuàng)建一個(gè)線程。當(dāng)多個(gè)用戶并發(fā)訪問Servlet共享資源的時(shí)候就會(huì)出現(xiàn)線程安全問題。

原則:

如果一個(gè)變量需要多個(gè)用戶共享,則應(yīng)當(dāng)在訪問該變量的時(shí)候,加同步機(jī)制synchronized (對(duì)象){}

如果一個(gè)變量不需要共享,則直接在 doGet() 或者 doPost()定義.這樣不會(huì)存在線程安全問題

load-on-startup

如果在元素中配置了一個(gè)元素,那么WEB應(yīng)用程序在啟動(dòng)時(shí),就會(huì)裝載并創(chuàng)建Servlet的實(shí)例對(duì)象、以及調(diào)用Servlet實(shí)例對(duì)象的init()方法

作用:

為web應(yīng)用寫一個(gè)InitServlet,這個(gè)servlet配置為啟動(dòng)時(shí)裝載,為整個(gè)web應(yīng)用創(chuàng)建必要的數(shù)據(jù)庫表和數(shù)據(jù)

完成一些定時(shí)的任務(wù)【定時(shí)寫日志,定時(shí)備份數(shù)據(jù)】

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

當(dāng)你啟動(dòng)Tomcat,你在網(wǎng)址上輸入http://localhost:8080。為什么會(huì)出現(xiàn)Tomcat小貓的頁面?

這是由缺省Servlet為你服務(wù)的!

我們先看一下web.xml文件中的配置,web.xml文件配置了一個(gè)缺省Servlet

    
        default
        org.apache.catalina.servlets.DefaultServlet
        
            debug
            0
        
        
            listings
            false
        
        1
    


    
        default
        /
    

什么叫做缺省Servlet?凡是在web.xml文件中找不到匹配的元素的URL,它們的訪問請(qǐng)求都將交給缺省Servlet處理,也就是說,缺省Servlet用于處理所有其他Servlet都不處理的訪問請(qǐng)求

既然我說了在web訪問任何資源都是在訪問Servlet,那么我訪問靜態(tài)資源【本地圖片,本地HTML文件】也是在訪問這個(gè)缺省Servlet【DefaultServlet】

證實(shí)一下:當(dāng)我沒有手工配置缺省Servlet的時(shí)候,訪問本地圖片是可以訪問得到的

現(xiàn)在我自己配置一個(gè)缺省Servlet,Demo1就是我手工配置的缺省Servlet,覆蓋掉web.xml配置的缺省Servlet

    
        Demo1
        zhongfucheng.web.Demo1
    

    
        Demo1
        /
    

下面我繼續(xù)訪問一下剛才的圖片,此時(shí)輸出的是Demo1這個(gè)Servlet寫上的內(nèi)容了

總結(jié):無論在web中訪問什么資源【包括JSP】,都是在訪問Servlet。沒有手工配置缺省Servlet的時(shí)候,你訪問靜態(tài)圖片,靜態(tài)網(wǎng)頁,缺省Servlet會(huì)在你web站點(diǎn)中尋找該圖片或網(wǎng)頁,如果有就返回給瀏覽器,沒有就報(bào)404錯(cuò)誤

ServletConfig對(duì)象 ServletConfig對(duì)象有什么用?
通過此對(duì)象可以讀取web.xml中配置的初始化參數(shù)。

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

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

獲取web.xml文件配置的參數(shù)信息

為Demo1這個(gè)Servlet配置一個(gè)參數(shù),參數(shù)名是name,值是zhongfucheng

    
        Demo1
        zhongfucheng.web.Demo1
        
            name
            zhongfucheng
        
    
    
        Demo1
        /Demo1
    

在Servlet中獲取ServletConfig對(duì)象,通過ServletConfig對(duì)象獲取在web.xml文件配置的參數(shù)

ServletContext對(duì)象 什么是ServletContext對(duì)象?

當(dāng)Tomcat啟動(dòng)的時(shí)候,就會(huì)創(chuàng)建一個(gè)ServletContext對(duì)象。它代表著當(dāng)前web站點(diǎn)

ServletContext有什么用?

ServletContext既然代表著當(dāng)前web站點(diǎn),那么所有Servlet都共享著一個(gè)ServletContext對(duì)象,所以Servlet之間可以通過ServletContext實(shí)現(xiàn)通訊。

ServletConfig獲取的是配置的是單個(gè)Servlet的參數(shù)信息,ServletContext可以獲取的是配置整個(gè)web站點(diǎn)的參數(shù)信息

利用ServletContext讀取web站點(diǎn)的資源文件

實(shí)現(xiàn)Servlet的轉(zhuǎn)發(fā)【用ServletContext轉(zhuǎn)發(fā)不多,主要用request轉(zhuǎn)發(fā)】

Servlet之間實(shí)現(xiàn)通訊

ServletContext對(duì)象可以被稱之為域?qū)ο?/strong>

到這里可能有一個(gè)疑問,域?qū)ο笫鞘裁茨??其?shí)域?qū)ο罂梢院唵卫斫獬?strong>一個(gè)容器【類似于Map集合】

實(shí)現(xiàn)Servlet之間通訊就要用到ServletContext的setAttribute(String name,Object obj)方法,
第一個(gè)參數(shù)是關(guān)鍵字,第二個(gè)參數(shù)是你要存儲(chǔ)的對(duì)象

這是Demo2的代碼

        //獲取到ServletContext對(duì)象
        ServletContext servletContext = this.getServletContext();

        String value = "zhongfucheng";

        //MyName作為關(guān)鍵字,value作為值存進(jìn)   域?qū)ο蟆绢愋陀贛ap集合】
        servletContext.setAttribute("MyName", value);

這是Demo3的代碼

        //獲取ServletContext對(duì)象
        ServletContext servletContext = this.getServletContext();

        //通過關(guān)鍵字獲取存儲(chǔ)在域?qū)ο蟮闹?        String value = (String) servletContext.getAttribute("MyName");

        System.out.println(value);

訪問Demo3可以獲取Demo2存儲(chǔ)的信息,從而實(shí)現(xiàn)多個(gè)Servlet之間通訊

獲取web站點(diǎn)配置的信息

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

web.xml文件支持對(duì)整個(gè)站點(diǎn)進(jìn)行配置參數(shù)信息所有Servlet都可以取到該參數(shù)信息

    
        name
        zhongfucheng
    

Demo4代碼

        //獲取到ServletContext對(duì)象
        ServletContext servletContext = this.getServletContext();

        //通過名稱獲取值
        String value = servletContext.getInitParameter("name");
        System.out.println(value);

試一下Demo3是否能拿到,相同的代碼

        //獲取到ServletContext對(duì)象
        ServletContext servletContext = this.getServletContext();

        //通過名稱獲取值
        String value = servletContext.getInitParameter("name");
        System.out.println(value);

讀取資源文件

第一種方式:

現(xiàn)在我要通過Servlet111讀取1.png圖片

按我們以前的方式,代碼應(yīng)該是這樣的。

        FileInputStream fileInputStream = new FileInputStream("1.png");
        System.out.println(fileInputStream);

當(dāng)我們?cè)L問的時(shí)候,卻出錯(cuò)了!說找不到1.png文件

這是為什么呢?我們以前讀取文件的時(shí)候,如果程序和文件在同一包名,可以直接通過文件名稱獲取得到的!,原因很簡單,以前我們寫的程序都是通過JVM來運(yùn)行的,而現(xiàn)在,我們是通過Tomcat來運(yùn)行的

根據(jù)web的目錄規(guī)范,Servlet編譯后的class文件是存放在WEB-INFclasses文件夾中的

看到這里,我們知道了要進(jìn)入classes目錄中讀取文件,所以我們將代碼改成以下方式


        FileInputStream fileInputStream = new FileInputStream("D:zhongfuchengwebWEB-INFclasseszhongfuchengweb1.png");
        System.out.println(fileInputStream);

再去讀取時(shí),就發(fā)現(xiàn)可以獲取到文件了。

但是現(xiàn)在問題又來了,我讀取文件的時(shí)候都要寫上絕對(duì)路徑,這樣太不靈活了。試想一下,如果我將該讀取文件的模塊移到其他的web站點(diǎn)上,我的代碼就又要修改了【因?yàn)閣eb站點(diǎn)的名字不一樣】。

我們通過ServletContext讀取就可以避免修改代碼的情況,因?yàn)镾ervletContext對(duì)象是根據(jù)當(dāng)前web站點(diǎn)而生成的

代碼如下所示:

        //獲取到ServletContext對(duì)象
        ServletContext servletContext = this.getServletContext();

        //調(diào)用ServletContext方法獲取到讀取文件的流
        InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/classes/zhongfucheng/web/1.png");

第二種方式:

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

代碼如下所示


        //獲取到ServletContext對(duì)象
        ServletContext servletContext = this.getServletContext();

        //調(diào)用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");


原則:如果文件太大,就不能用類裝載器的方式去讀取,會(huì)導(dǎo)致內(nèi)存溢出

如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號(hào):Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68412.html

相關(guān)文章

  • Java3y文章目錄導(dǎo)航

    摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...

    KevinYan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<