柚子快報(bào)邀請(qǐng)碼778899分享:學(xué)習(xí)Servlet
柚子快報(bào)邀請(qǐng)碼778899分享:學(xué)習(xí)Servlet
什么是Servlet?
Servlet是sun公司提供的一門(mén)用于開(kāi)發(fā)動(dòng)態(tài)web資源的技術(shù),可以實(shí)現(xiàn)和客戶端的交互,接收客戶端請(qǐng)求和給客戶端返回響應(yīng)。
Servlet的實(shí)現(xiàn)類(lèi)
Servlet接口SUN公司定義了兩個(gè)默認(rèn)實(shí)現(xiàn)類(lèi),分別為:GenericServlet、HttpServlet。
HttpServlet指能夠處理HTTP請(qǐng)求的servlet,它在原有Servlet接口上添加了一些與HTTP協(xié)議處理方法,它比Servlet接口的功能更為強(qiáng)大。因此開(kāi)發(fā)人員在編寫(xiě)Servlet時(shí),通常應(yīng)繼承這個(gè)類(lèi),而避免直接去實(shí)現(xiàn)Servlet接口。
HttpServlet在實(shí)現(xiàn)Servlet接口時(shí),覆寫(xiě)了service方法,該方法體內(nèi)的代碼會(huì)自動(dòng)判斷用戶的請(qǐng)求方式,如為GET請(qǐng)求,則調(diào)用HttpServlet的doGet方法,如為Post請(qǐng)求,則調(diào)用doPost方法。因此,開(kāi)發(fā)人員在編寫(xiě)Servlet時(shí),通常只需要覆寫(xiě)doGet或doPost方法,而不要去覆寫(xiě)service方法
Servlet的生命周期
Servlet是一個(gè)供其他Java程序(Servlet引擎)調(diào)用的Java類(lèi),它不能獨(dú)立運(yùn)行,它的運(yùn)行完全由Servlet引擎來(lái)控制和調(diào)度。
針對(duì)客戶端的多次Servlet請(qǐng)求,通常情況下,服務(wù)器只會(huì)創(chuàng)建一個(gè)Servlet實(shí)例對(duì)象,也就是說(shuō)Servlet實(shí)例對(duì)象一旦創(chuàng)建,它就會(huì)駐留在內(nèi)存中,為后續(xù)的其它請(qǐng)求服務(wù),直至web容器退出,servlet實(shí)例對(duì)象才會(huì)銷(xiāo)毀。
在Servlet的整個(gè)生命周期內(nèi),Servlet的init方法只被調(diào)用一次。而對(duì)一個(gè)Servlet的每次訪問(wèn)請(qǐng)求都導(dǎo)致Servlet引擎調(diào)用一次servlet的service方法。對(duì)于每次訪問(wèn)請(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方法。
如果在
用途:為web應(yīng)用寫(xiě)一個(gè)InitServlet,這個(gè)servlet配置為啟動(dòng)時(shí)裝載,為整個(gè)web應(yīng)用創(chuàng)建必要的公共數(shù)據(jù)。
Servlet線程安全問(wèn)題
出現(xiàn)原因
多個(gè)客戶端訪問(wèn)同一個(gè)Servlet中的資源時(shí),有可能會(huì)出現(xiàn)線程安全問(wèn)題
出現(xiàn)問(wèn)題案例
public class MyServlet extends HttpServlet{
? ?private static final long serialVersionUID = 1L;
int num = 0;
? ? ?
? ?public MyServlet() {
? System.out.println("MyServlet被創(chuàng)建");
? }
?
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
?
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
num++;
try {
? ?Thread.sleep(10000);
} catch (InterruptedException e) {
? ?e.printStackTrace();
}
response.getOutputStream().println(num);
}
}
解決方案
1.將Servlet實(shí)現(xiàn)SingleThreadModel(已過(guò)時(shí)),因?yàn)楫?dāng)線程阻塞,就會(huì)創(chuàng)建新的Servlet對(duì)象
2.利用線程鎖機(jī)制, synchronized或lock
public class MyServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
int num = 0;
private Lock lock = new ReentrantLock();
? ? ?
? ?public MyServlet() {
? System.out.println("MyServlet被創(chuàng)建");
? }
?
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
?
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
lock.lock();//上鎖
num++;
try {
? ?Thread.sleep(5000);
} catch (InterruptedException e) {
? ?e.printStackTrace();
}
response.getOutputStream().println(num);
lock.unlock();//解鎖
}
}
經(jīng)驗(yàn):盡可能的不使用成員變量,而是使用局部變量
Servlet是否是單例的?
不是單例的 但在一般情況是單例的 如果Servlet實(shí)現(xiàn)了SingleThreadModel接口,該Servlet對(duì)象在第一次線程阻塞時(shí)會(huì)創(chuàng)建新的對(duì)象 -- 已過(guò)時(shí)
柚子快報(bào)邀請(qǐng)碼778899分享:學(xué)習(xí)Servlet
推薦鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。