更新時(shí)間:2021-07-12 來源:黑馬程序員 瀏覽量:
(1)問題分析:
考官主要想考核Java基本功的掌握和應(yīng)用。一方面,是servlet的生命周期;另一方面,則是其單例非線程安全對(duì)于安全這塊的一個(gè)處理。
(2)核心答案講解:
1)init()方法
在Servlet的生命周期中,僅執(zhí)行一次init()方法,它是在服務(wù)器裝入Servlet 時(shí)執(zhí)行的,可以配置服務(wù)器,以在啟動(dòng)服務(wù)器或客戶機(jī)首次訪問Servlet時(shí)裝入 Servlet。無論有多少客戶機(jī)訪問Servlet,都不會(huì)重復(fù)執(zhí)行init();
2)service()方法
它是Servlet的核心,每當(dāng)一個(gè)客戶請(qǐng)求一個(gè)HttpServlet對(duì)象,該對(duì)象的 Service()方法就要調(diào)用,而且傳遞給這個(gè)方法一個(gè)“請(qǐng)求”(ServletRequest) 對(duì)象和一個(gè)“響應(yīng)”(ServletResponse)對(duì)象作為參數(shù)。在HttpServlet中已存 在Service()方法。默認(rèn)的服務(wù)功能是調(diào)用與HTTP請(qǐng)求的方法相應(yīng)的do功能。
3)destroy()方法
僅執(zhí)行一次,在服務(wù)器端停止且卸載Servlet時(shí)執(zhí)行該方法,有點(diǎn)類似于C++的 delete方法。一個(gè)Servlet在運(yùn)行service()方法時(shí)可能會(huì)產(chǎn)生其他的線程,因 此需要確認(rèn)在調(diào)用destroy()方法時(shí),這些線程已經(jīng)終止或完成。
(3)問題擴(kuò)展
如何解決servlet線程安全:
第一種,繼承SingleThreadModel但是這樣每次都會(huì)創(chuàng)建一個(gè)新的servlet實(shí)例, 但這樣消耗服務(wù)器的內(nèi)存,降低了性能,并且這個(gè)接口現(xiàn)在已經(jīng)過時(shí)了,不推薦使 用。
第二種:我們盡量避免使用全局變量,就我個(gè)人而言,我比較喜歡使用這種方法。
第三種,我們可以通過使用ThreadLocal, 內(nèi)部結(jié)構(gòu)是一個(gè)Map結(jié)構(gòu),用當(dāng)前線 程作為key,他會(huì)創(chuàng)建多個(gè)副本。get,set方法
第四種,我們當(dāng)然還可以來加鎖,進(jìn)行解決線程問題。
而且我還知道,向我們這種常用的MVC框架,struts1,spring這些MVC框架,都 是基于servlet發(fā)展而來的,就比如struts1 的核心總控制器是ActionServlet, 而springMVC的前端總控制器是dispatchServlet,在項(xiàng)目我們?cè)?jīng)用serlet來 生成 圖片驗(yàn)證碼的,防止用戶進(jìn)行暴力破解。
(4)結(jié)合項(xiàng)目中使用
servlet的配置文件 web.xml
ImageCodeServlet org.leopard.code.ImageCodeServlet ImageCodeServlet /d
描述:
在web.xml中,首先需要寫一個(gè)servlet標(biāo)簽,servlet標(biāo)簽中有兩個(gè)子標(biāo)簽,一個(gè)叫servlet-name,這個(gè)name可以隨便起,但是要保證唯一性,除此之外,在這個(gè)servlet-name下有一個(gè)servlet-class,這個(gè)servlet-class對(duì)應(yīng)的就是我后臺(tái)提高服務(wù)的servlet,除此之外還有一個(gè)servlet-mapping,這個(gè)里邊首先有一個(gè)servl-name。,這個(gè)servl-name首先要保證和上邊的servlet-name保持一致,除此之外還有一個(gè)url-pattern,這是一個(gè)虛擬路徑,是用來發(fā)送請(qǐng)求的url地址。
Servlet的生命周期是由Servlet容器來控制的,它始于裝入Web服務(wù)器的內(nèi)存時(shí),并在終止或重新裝入Servlet時(shí)結(jié)束。
在代碼中,Servlet生命周期由接口javax.servlet.Servlet定義。所有的Java Servlet 必須直接或間接地實(shí)現(xiàn)javax.servlet.Servlet接口,這樣才能在Servlet Engine上運(yùn)行。
Java培訓(xùn)之ServletContext的介紹與獲取