亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

3 Servlet監聽器

2019-11-14 22:52:46
字體:
來源:轉載
供稿:網友
3 Servlet監聽器作者:禪樓望月(http://www.49028c.com/yaoyinglong) 1. ServletConfig和ServletContext 1.1 ServletConfig和ServletContext配置和使用

一些和業務邏輯無關的信息不應該放在硬編碼到程序中,一般將其放在ServletConfig或ServletContext。

在web.xml文件中配置ServletConfig和ServletContext參數:

<!-- 配置ServletContext參數 --><context-param>      <param-name>email</param-name>      <param-value>yaoyinglong@Gmail.com</param-value></context-param>
<servlet>  <servlet-name>Test</servlet-name>  <servlet-class>com.yyl.Test</servlet-class>  <!-- 配置ServletConfig參數 -->  <init-param>        <param-name>email</param-name>        <param-value>yaoyinglong@gmail.com</param-value>    </init-param></servlet>

我們可以清楚的看到:ServletConfig參數配置在<servlet> 節點內部;而ServletContext參數配置在<servlet> 節點外部。

使用ServletConfig和ServletContext參數:

String servletConfigEmail=getServletConfig().getInitParameter("email");String servletContextEmail=getServletContext().getInitParameter("email");

不用說大家值也只那行去那個參數了。

ServletConfig和ServletContext參數的使用范圍:

ServletConfig參數:

①只可以在配置了它的servlet中可用;

②在java對象變為Servlet之前不可用(init函數有兩個版本,一般情況下不要覆蓋接受ServletConfig對象的那個版本嗎,即是要覆蓋也應該加上super.init(ServletConfig))。

③ServletConfig參數只在Servlet初始化是讀取一次,中途不能修改。

ServletContext對Web應用中的所有servlet和jsp都可用。

1.2 ServletConfig和ServletContext舉例

這兩個對象非常重要,當我們程序需要讀取配置文件的時候便可以將在這里配置配置文件的路徑,下面以SPRing配置來說明:

我們如果通過MyEclipse使用Spring框架時,它會幫我們將Spring配置好,無需勞您大駕親自動手,但是如果你使用的是Eclipse的時候,抱歉,它可沒那么貼心了,只能我們自己手動來配了,無論是IDE幫我們配還是我們自己手動來陪,很多時候都是Ctrl+C和Ctrl+V,可是你知道Spring是怎么做的嗎?知道的請略過,或者您可以看看我說的是不是正確,指出錯誤之處(感激不盡?。?!紅玫瑰,不知道的就請跟著我一起看看吧:

首先來看為什么要在web.xml中配置Spring:

不在web.xml中配置Spring時,我們要獲取配置在Spring的bean時我們是這樣做的:

import org.springframework.beans.factory.BeanFactory;import org.springframework.context.support.ClassPathXmlapplicationContext;public class Test {    public static void main(String[] args) {        BeanFactory beanFactory=new ClassPathXmlApplicationContext("appclicationContext.xml");        beanFactory.getBean("beanId");    }}

C/S端可以這么做,那么B/S端呢?我們可以用一個Servlet來實現:

public void doGet(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException {    BeanFactory beanFactory=new ClassPathXmlApplicationContext("applicationContext.xml");    getServletContext().setAttribute("beanFactory", beanFactory);}

這樣配置了之后,在Web應用的所有JSP和Servlet中都可以使用BeanFactory了。

還有一種配置方式就是我們下面要講到的監聽器(可以先看一下下面的內容在回來):

@Overridepublic void contextDestroyed(ServletContextEvent sce) {    BeanFactory beanFactory=new ClassPathXmlApplicationContext("applicationContext.xml");    sce.getServletContext().setAttribute("beanFactory", beanFactory);}

驚訝大家有沒有發現無論用什么方法配,代碼都是一樣的。Spring框架開發者,也發現了這件事情,于是他們就把這件事情給做了(他們提供了后兩種的實現),我們都知道,Servlet和監聽器都是要在web.xml中配置的。因此我們工作就是把Spring框架開發者幫我們實現好的Servlet和監聽器配置到web.xml中。

注:我這里只是簡單的說明最核心的部分,強大的Spring要做的工作遠比我這里做的多的多大笑,并且我這里將application.xml配置文件的路徑硬編碼到了程序里,這是不好的,應該使用我們現在講的ServletConfig和ServletContext參數配置到xml文件中。

我們看看Spring到底是怎么做的:

image

哈哈,我沒有騙大家吧,Spring為我們實現了Servlet和Listener的配置方式。不過大多數情況下我們都是用Listener來配置的。那我們進到這個監聽器中看看:

public class ContextLoaderListener implements ServletContextListener {    private ContextLoader contextLoader;    public void contextInitialized(ServletContextEvent event) {        this.contextLoader = createContextLoader();        this.contextLoader.initWebApplicationContext(event.getServletContext());    }    protected ContextLoader createContextLoader() {        return new ContextLoader();    }    public ContextLoader getContextLoader() {        return this.contextLoader;    }    public void contextDestroyed(ServletContextEvent event) {        if (this.contextLoader != null) {            this.contextLoader.closeWebApplicationContext(event.getServletContext());        }    }}

我們發現他在Web應用啟動時,做了兩件事情:創建ContextLoader類,然后調用它的initWebApplicationContext方法,進入該方法:

public WebApplicationContext initWebApplicationContext(ServletContext servletContext)            throws IllegalStateException, BeansException {        // 考慮到篇幅的太大故將一些我們暫時不關心的部分刪掉了……        try {            // Determine parent for root web application context, if any.            ApplicationContext parent = loadParentContext(servletContext);            // Store context in local instance variable, to guarantee that            // it is available on ServletContext shutdown.            this.context = createWebApplicationContext(servletContext, parent);            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);            currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this.context);            // 考慮到篇幅的太大故將一些我們暫時不關心的部分刪掉了……
    }

從黃底加粗的代碼中我們可以清楚的看到:先創建了WebApplicationContext對象,然后將其保存到了servletContext中(即Application范圍內)。以后Struts2和Spring繼承插件就可以從Application中獲取BeanFactory,通過BeanFactory取得Ioc容器中的Actoin對象,這樣Action的依賴對象都會被注入。

那么我再跟蹤createWebApplicationContext函數:

protected WebApplicationContext createWebApplicationContext(            ServletContext servletContext, ApplicationContext parent) throws BeansException {        Class contextClass = determineContextClass(servletContext);            // 考慮到篇幅的太大故將一些我們暫時不關心的部分刪掉了……
               ConfigurableWebApplicationContext wac =                (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);        wac.setParent(parent);        wac.setServletContext(servletContext);        //這里讀取web.xml文件中的 <context-param>節點中的值        wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));        customizeContext(servletContext, wac);        wac.refresh();        return wac;    }

從黃底加粗的代碼指示我們必須在web.xml文件中配置<context-param>參數,至于配什么呢,<param-value>參數的值我們知道,肯定是要applicationContext.xml文件的路徑,參數的名字是什么呢?往后看,它從那個參數讀,我們就用那個參數組為的<param-name>值。

查看CONFIG_LOCATION_PARAM常量:

c00148f7-d4a1-4a0b-805d-9a81af29d1d4

所以我們的<param-name>的值為contextConfigLocation。

誒!前面我們不是說創建BeanFactory嗎?怎么這里創建的是WebApplicationContext呢?經跟蹤發現它繼承自BeanFactory,主要使用BeanFactory的getBean方法來獲取Bean。

這下明白我在web.xml中使用監聽器配置Spring的含義了吧。

那么如果我們使用Servlet怎么配置呢?(不懂的可以留言,這里就不浪費篇幅了)。

1.3 ServletContext不是線程安全的

應用中的每一部分都能訪問到ServletContext,因此,必要時應該對其同步:

synchronized (getServletContext()) {    //業務邏輯代碼}
2. 監聽器(Listener)

所謂監聽者就是,當你做某一件事情的時候,另一個類關注著你,并且采取相應的行動。

2.1 ServletContextListener

image

查看API可知,它監聽Web應用初始化和Web應用銷毀動作,那我們就可以指示該監聽者,在Web應用初始化和Web應用銷毀時幫我們干我們想干的事情:

public class TestServletContextListener implements ServletContextListener {    @Override    public void contextDestroyed(ServletContextEvent sce) {        System.out.println("Oh,my god! I was killed");    }    @Override    public void contextInitialized(ServletContextEvent sce) {        System.out.println("houhou, God created me");        String email=sce.getServletContext().getInitParameter("email");        System.out.println("My Email is "+email);    }}

這樣它就能聽我們的話了嗎?還不行,因為Tomcat不會看你實現了ServletContextListener接口就會讓它去監視Web應用的初始化和銷毀。Tomcat只會處理你在web.xml文件中配置了的事情。因此還需在web.xml中配置監聽:

在節點下添加:

<listener>      <listener-class>com.yyl.TestServletContextListener</listener-class>  </listener>

現在配置就完成了,ServletContextListener的實現者已經為我所用了,不行你看看:

當我啟動Tomcat時:

image

當我們關閉Tomcat時:

image

到這里您是不是有個疑問:Tomcat怎么知道你配的這個com.yyl.TestServletContextListener是用來監聽Web應用的創建于銷毀動作呢,即這個監聽者是ServletContext監聽者?因為Servlet還有很多其他監聽者(后面會一一登場亮相)。這是因為Web容器會會檢查類,檢查它繼承了那個監聽接口,或者多個監聽接口,據此明確它來監聽什么類型的事件。

3. 監聽器有8種(8種接口)

ServletContextAttributeListener:監聽在ServletContext對象中添加、刪除、替換屬性的動作。

HttpsessionListener:監聽Web應用Session的創建于銷毀。據此可以知道有多少并發用戶。

ServletRequestListener監聽瀏覽器請求Servlet動作。

ServletRequestAttrubuteListener監聽在ServletRequest對象中請求中添加、刪除、替換屬性的動作。

HttpSessionBindingListener屬性本身在被添加到session中或從session中刪除時得到通知。

HttpSesionAttributeListener監聽在HttpSession中增加、刪除、替換屬性的動作。

servletContextListener:監聽Web應用創建或撤銷動作。

HttpSessionActivationListener:當一個Session被遷移到另一個JVM中通知實現了該接口的屬性做好準備。

今天實在沒有精力一一舉例了,下篇吧!困了


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久九九热免费视频| 亚洲tv在线观看| 激情亚洲一区二区三区四区| 大荫蒂欧美视频另类xxxx| 亚州欧美日韩中文视频| 成人国产精品久久久久久亚洲| 国产视频一区在线| 亚洲精品资源美女情侣酒店| 91午夜理伦私人影院| 国产aⅴ夜夜欢一区二区三区| 亚洲国产精品人久久电影| 日韩高清电影免费观看完整版| 欧美在线亚洲在线| 欧美性一区二区三区| 国产日韩在线视频| 粉嫩av一区二区三区免费野| 日韩亚洲一区二区| 91视频九色网站| 国产精品jizz在线观看麻豆| 亚洲电影免费在线观看| 91精品在线看| 97国产精品免费视频| 97在线视频国产| 亚洲国产欧美久久| 成人激情视频小说免费下载| 伊人激情综合网| 91在线免费观看网站| 国产精品久久久久久超碰| 国产一区在线播放| 国内精品中文字幕| 久久视频在线播放| 午夜精品视频网站| 91国产美女在线观看| 日韩av三级在线观看| 亚洲高清不卡av| 国产欧美va欧美va香蕉在线| 国产精品成人aaaaa网站| 国模极品一区二区三区| 精品国产一区二区三区久久久| 精品少妇v888av| 中文字幕欧美精品日韩中文字幕| 视频在线观看一区二区| 深夜福利国产精品| 国产精品国产亚洲伊人久久| 欧美一区二区三区精品电影| 日韩av电影在线免费播放| 亚洲小视频在线| 日韩精品中文字| 国产午夜精品麻豆| 国产精品久久久久久亚洲调教| 欧美性极品xxxx娇小| 国产精品入口日韩视频大尺度| 日韩在线观看网站| 亚洲a区在线视频| 国产日韩精品视频| 色婷婷久久一区二区| 亚洲福利视频免费观看| 久久精品国产v日韩v亚洲| 亚洲香蕉av在线一区二区三区| 精品视频久久久久久| 欧美成人精品在线| 在线观看日韩av| 欧美日韩在线视频一区二区| 欧美激情在线播放| 欧美日韩一区二区三区在线免费观看| 国产91在线播放精品91| 国产精品久久久久久超碰| 欧美电影免费在线观看| 久久成人国产精品| 成人av资源在线播放| 亚洲欧美日韩国产成人| 日韩精品中文字幕有码专区| 亚洲欧美成人在线| 国产99久久精品一区二区| 美女啪啪无遮挡免费久久网站| 乱亲女秽乱长久久久| 91精品久久久久久久久久久| 日韩成人中文字幕在线观看| 黑人狂躁日本妞一区二区三区| 久久久国产精品x99av| 国产精品99久久99久久久二8| 成人福利网站在线观看| 精品日韩视频在线观看| 奇门遁甲1982国语版免费观看高清| 国产精品亚发布| 欧美性极品少妇精品网站| 姬川优奈aav一区二区| 日韩欧美a级成人黄色| 一区二区福利视频| 精品国产鲁一鲁一区二区张丽| 精品视频久久久久久| 91高清视频免费| 亚洲欧美日韩一区二区三区在线| 国产成人一区二区| www.日韩免费| 国产精品黄色影片导航在线观看| 亚洲天堂男人天堂| 91欧美精品成人综合在线观看| 精品视频—区二区三区免费| 国产视频精品在线| 欧美精品一区在线播放| 乱亲女秽乱长久久久| 91久久嫩草影院一区二区| 亚洲va欧美va在线观看| xxx欧美精品| 亚洲国产成人久久| 欧美日本啪啪无遮挡网站| 欧美日韩精品国产| 国产精品啪视频| 日韩男女性生活视频| 51久久精品夜色国产麻豆| 91av免费观看91av精品在线| 97人人爽人人喊人人模波多| 亚洲午夜未满十八勿入免费观看全集| 欧美性猛交xxxx偷拍洗澡| 亚洲精品动漫久久久久| 日韩欧美成人网| 97热在线精品视频在线观看| 国产精品视频精品视频| 91精品国产自产在线老师啪| 国产精品久久久久久亚洲影视| 国产一区二区视频在线观看| 黄色成人在线免费| 国产一区二区久久精品| 91网站免费看| 日韩av资源在线播放| 中文字幕亚洲综合久久筱田步美| 国产精品91久久久久久| 在线精品视频视频中文字幕| 久久久久久成人精品| 亚洲免费人成在线视频观看| 日韩在线观看网址| 亚洲天堂成人在线视频| 亚洲老司机av| 在线看欧美日韩| 国产精品久久中文| 亚洲国内精品在线| 亚洲国产精品va在线| 欧美激情视频免费观看| 欧美中文字幕精品| 亚洲欧美日本精品| 中文字幕精品一区久久久久| 日韩欧美在线一区| 日本aⅴ大伊香蕉精品视频| 91精品久久久久久久久| 亚洲第一黄色网| 主播福利视频一区| 亚洲精品视频在线观看视频| 国产精品高清免费在线观看| 欧美亚洲国产另类| 亚洲欧美成人网| 国产经典一区二区| 国产高清在线不卡| 97在线视频免费| 久久久久久久久久国产| 久久久精品2019中文字幕神马| 亚洲欧美激情精品一区二区| 日韩中文字幕视频在线| 欧美成人激情视频| 亚洲美女动态图120秒| 久久九九免费视频| 亚洲欧美日韩中文视频| 久久久久中文字幕2018| 国产精品黄色影片导航在线观看|