日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Servlet简介

發(fā)布時間:2024/4/17 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Servlet简介 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Servlet程序是由WEB服務(wù)器調(diào)用,web服務(wù)器收到客戶端的Servlet訪問請求后:
  ①Web服務(wù)器首先檢查是否已經(jīng)裝載并創(chuàng)建了該Servlet的實(shí)例對象。如果是,則直接執(zhí)行第④步,否則,執(zhí)行第②步。
  ②裝載并創(chuàng)建該Servlet的一個實(shí)例對象。?
  ③調(diào)用Servlet實(shí)例對象的init()方法。
  ④創(chuàng)建一個用于封裝HTTP請求消息的HttpServletRequest對象和一個代表HTTP響應(yīng)消息的HttpServletResponse對象,然后調(diào)用Servlet的service()方法并將請求和響應(yīng) ? ? ? ? ? 對象作為參數(shù)傳遞進(jìn)去。
  ⑤WEB應(yīng)用程序被停止或重新啟動之前,Servlet引擎將卸載Servlet,并在卸載之前調(diào)用Servlet的destroy()方法。

 

?

在eclipse中新建一個web project工程,eclipse會自動創(chuàng)建下圖所示目錄結(jié)構(gòu):

 

接口實(shí)現(xiàn)類

  Servlet接口SUN公司定義了兩個默認(rèn)實(shí)現(xiàn)類,分別為:GenericServlet、HttpServlet。

  HttpServlet指能夠處理HTTP請求的servlet,它在原有Servlet接口上添加了一些與HTTP協(xié)議處理方法,它比Servlet接口的功能更為強(qiáng)大。因此開發(fā)人員在編寫Servlet時,通常應(yīng)繼承這個類,而避免直接去實(shí)現(xiàn)Servlet接口。
  HttpServlet在實(shí)現(xiàn)Servlet接口時,覆寫了service方法,該方法體內(nèi)的代碼會自動判斷用戶的請求方式,如為GET請求,則調(diào)用HttpServlet的doGet方法,如為Post請求,則調(diào)用doPost方法。因此,開發(fā)人員在編寫Servlet時,通常只需要覆寫doGet或doPost方法,而不要去覆寫service方法。

通過Eclipse創(chuàng)建和編寫Servlet

  選中g(shù)acl.servlet.study包,右鍵→New→Servlet,如下圖所示:

  

  

  

  這樣,我們就通過Eclipse幫我們創(chuàng)建好一個名字為ServletDemo1的Servlet,創(chuàng)建好的ServletDemo01里面會有如下代碼:

1 package gacl.servlet.study;2 3 import java.io.IOException;4 import java.io.PrintWriter;5 6 import javax.servlet.ServletException;7 import javax.servlet.http.HttpServlet;8 import javax.servlet.http.HttpServletRequest;9 import javax.servlet.http.HttpServletResponse; 10 11 public class ServletDemo1 extends HttpServlet { 12 13 /** 14 * The doGet method of the servlet. <br> 15 * 16 * This method is called when a form has its tag value method equals to get. 17 * 18 * @param request the request send by the client to the server 19 * @param response the response send by the server to the client 20 * @throws ServletException if an error occurred 21 * @throws IOException if an error occurred 22 */ 23 public void doGet(HttpServletRequest request, HttpServletResponse response) 24 throws ServletException, IOException { 25 26 response.setContentType("text/html"); 27 PrintWriter out = response.getWriter(); 28 out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); 29 out.println("<HTML>"); 30 out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); 31 out.println(" <BODY>"); 32 out.print(" This is "); 33 out.print(this.getClass()); 34 out.println(", using the GET method"); 35 out.println(" </BODY>"); 36 out.println("</HTML>"); 37 out.flush(); 38 out.close(); 39 } 40 41 /** 42 * The doPost method of the servlet. <br> 43 * 44 * This method is called when a form has its tag value method equals to post. 45 * 46 * @param request the request send by the client to the server 47 * @param response the response send by the server to the client 48 * @throws ServletException if an error occurred 49 * @throws IOException if an error occurred 50 */ 51 public void doPost(HttpServletRequest request, HttpServletResponse response) 52 throws ServletException, IOException { 53 54 response.setContentType("text/html"); 55 PrintWriter out = response.getWriter(); 56 out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); 57 out.println("<HTML>"); 58 out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); 59 out.println(" <BODY>"); 60 out.print(" This is "); 61 out.print(this.getClass()); 62 out.println(", using the POST method"); 63 out.println(" </BODY>"); 64 out.println("</HTML>"); 65 out.flush(); 66 out.close(); 67 } 68 69 }

  這些代碼都是Eclipse自動生成的,而web.xml文件中也多了<servlet></servlet>和<servlet-mapping></servlet-mapping>兩對標(biāo)簽,這兩對標(biāo)簽是配置ServletDemo1的,如下圖所示:

然后我們就可以通過瀏覽器訪問ServletDemo1這個Servlet,如下圖所示:

  

?

同一個Servlet可以被映射到多個URL上,即多個<servlet-mapping>元素的<servlet-name>子元素的設(shè)置值可以是同一個Servlet的注冊名

1 <servlet>2 <servlet-name>ServletDemo1</servlet-name>3 <servlet-class>gacl.servlet.study.ServletDemo1</servlet-class>4 </servlet>5 6 <servlet-mapping>7 <servlet-name>ServletDemo1</servlet-name>8 <url-pattern>/servlet/ServletDemo1</url-pattern>9 </servlet-mapping> 10 <servlet-mapping> 11 <servlet-name>ServletDemo1</servlet-name> 12 <url-pattern>/1.htm</url-pattern> 13 </servlet-mapping> 14 <servlet-mapping> 15 <servlet-name>ServletDemo1</servlet-name> 16 <url-pattern>/2.jsp</url-pattern> 17 </servlet-mapping> 18 <servlet-mapping> 19 <servlet-name>ServletDemo1</servlet-name> 20 <url-pattern>/3.php</url-pattern> 21 </servlet-mapping> 22 <servlet-mapping> 23 <servlet-name>ServletDemo1</servlet-name> 24 <url-pattern>/4.ASPX</url-pattern> 25 </servlet-mapping>

通過上面的配置,當(dāng)我們想訪問名稱是ServletDemo1的Servlet,可以使用如下的幾個地址去訪問:

  http://localhost:8080/JavaWeb_Servlet_Study_20140531/servlet/ServletDemo1

  http://localhost:8080/JavaWeb_Servlet_Study_20140531/1.htm

  http://localhost:8080/JavaWeb_Servlet_Study_20140531/2.jsp

  http://localhost:8080/JavaWeb_Servlet_Study_20140531/3.php

  http://localhost:8080/JavaWeb_Servlet_Study_20140531/4.ASPX

  ServletDemo1被映射到了多個URL上。

?

Servlet訪問URL使用*通配符映射

在Servlet映射到的URL中也可以使用*通配符,但是只能有兩種固定的格式:一種格式是"*.擴(kuò)展名",另一種格式是以正斜杠(/)開頭并以"/*"結(jié)尾。例如:

  

1 <servlet> 2 <servlet-name>ServletDemo1</servlet-name> 3 <servlet-class>gacl.servlet.study.ServletDemo1</servlet-class> 4 </servlet> 5 6 <servlet-mapping> 7 <servlet-name>ServletDemo1</servlet-name> 8 <url-pattern>/*</url-pattern>

?

Servlet與普通Java類的區(qū)別  

  Servlet是一個供其他Java程序(Servlet引擎)調(diào)用的Java類,它不能獨(dú)立運(yùn)行,它的運(yùn)行完全由Servlet引擎來控制和調(diào)度
  針對客戶端的多次Servlet請求,通常情況下,服務(wù)器只會創(chuàng)建一個Servlet實(shí)例對象,也就是說Servlet實(shí)例對象一旦創(chuàng)建,它就會駐留在內(nèi)存中,為后續(xù)的其它請求服務(wù),直至web容器退出,servlet實(shí)例對象才會銷毀
  在Servlet的整個生命周期內(nèi),Servlet的init方法只被調(diào)用一次。而對一個Servlet的每次訪問請求都導(dǎo)致Servlet引擎調(diào)用一次servlet的service方法。對于每次訪問請求,Servlet引擎都會創(chuàng)建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應(yīng)對象,然后將這兩個對象作為參數(shù)傳遞給它調(diào)用的Servlet的service()方法,service方法再根據(jù)請求方式分別調(diào)用doXXX方法。

  如果在<servlet>元素中配置了一個<load-on-startup>元素,那么WEB應(yīng)用程序在啟動時,就會裝載并創(chuàng)建Servlet的實(shí)例對象、以及調(diào)用Servlet實(shí)例對象的init()方法
?? ?舉例:
?? ?<servlet>
?? ??? ?<servlet-name>invoker</servlet-name>
?? ??? ?<servlet-class>
?? ??? ??? ?org.apache.catalina.servlets.InvokerServlet
?? ??? ?</servlet-class>
?? ??? ?<load-on-startup>1</load-on-startup>
?? ?</servlet>

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

?

如下一段配置,熟悉DWR的再熟悉不過了:
<servlet>
?? <servlet-name>dwr-invoker</servlet-name>
?? <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
?? <init-param>
??? <param-name>debug</param-name>
??? <param-value>true</param-value>
?? </init-param>
?? <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
?? <servlet-name>dwr-invoker</servlet-name>
?? <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

我們注意到它里面包含了這段配置:<load-on-startup>1</load-on-startup>,那么這個配置有什么作用呢?

貼一段英文原汁原味的解釋如下:
Servlet specification:
The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses.?? If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.

翻譯過來的意思大致如下:
1)load-on-startup元素標(biāo)記容器是否在啟動的時候就加載這個servlet(實(shí)例化并調(diào)用其init()方法)。

2)它的值必須是一個整數(shù),表示servlet應(yīng)該被載入的順序

2)當(dāng)值為0或者大于0時,表示容器在應(yīng)用啟動時就加載并初始化這個servlet;

3)當(dāng)值小于0或者沒有指定時,則表示容器在該servlet被選擇時才會去加載。

4)正數(shù)的值越小,該servlet的優(yōu)先級越高,應(yīng)用啟動時就越先加載。

5)當(dāng)值相同時,容器就會自己選擇順序來加載。

所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是優(yōu)先級,而非啟動延遲時間。

如下題目:

2.web.xml中不包括哪些定義(多選)

?

a.默認(rèn)起始頁

b.servlet啟動延遲時間定義

c.error處理頁面

d.jsp文件改動后重新載入時間

答案:b,d

通常大多數(shù)Servlet是在用戶第一次請求的時候由應(yīng)用服務(wù)器創(chuàng)建并初始化,但<load-on-startup>n</load-on-startup>?? 可以用來改變這種狀況,根據(jù)自己需要改變加載的優(yōu)先級!

?

缺省Servlet用于處理所有其他Servlet都不處理的訪問請求(在web.xml文件中找不到匹配的<servlet-mapping>元素的URL)

1 <servlet>2 <servlet-name>ServletDemo2</servlet-name>3 <servlet-class>gacl.servlet.study.ServletDemo2</servlet-class>4 <load-on-startup>1</load-on-startup>5 </servlet>6 7 <!-- 將ServletDemo2配置成缺省Servlet -->8 <servlet-mapping>9 <servlet-name>ServletDemo2</servlet-name> 10 <url-pattern>/</url-pattern> 11 </servlet-mapping>

?

?

在<tomcat的安裝目錄>\conf\web.xml文件中,注冊了一個名稱為org.apache.catalina.servlets.DefaultServlet的Servlet,并將這個Servlet設(shè)置為了缺省Servlet。

1 <servlet>2 <servlet-name>default</servlet-name>3 <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>4 <init-param>5 <param-name>debug</param-name>6 <param-value>0</param-value>7 </init-param>8 <init-param>9 <param-name>listings</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 <load-on-startup>1</load-on-startup> 13 </servlet> 14 15 <!-- The mapping for the default servlet --> 16 <servlet-mapping> 17 <servlet-name>default</servlet-name> 18 <url-pattern>/</url-pattern> 19 </servlet-mapping>

  當(dāng)訪問Tomcat服務(wù)器中的某個靜態(tài)HTML文件和圖片時,實(shí)際上是在訪問這個缺省Servlet。

?

Servlet的線程安全問題

當(dāng)多個客戶端并發(fā)訪問同一個Servlet時,web服務(wù)器會為每一個客戶端的訪問請求創(chuàng)建一個線程,并在這個線程上調(diào)用Servlet的service方法,因此service方法內(nèi)如果訪問了同一個資源的話,就有可能引發(fā)線程安全問題

上面的定義的是局部變量,所以不存在線程安全問題

?

把 i 定義成全局變量,當(dāng)多個線程并發(fā)訪問變量i時,就會存在線程安全問題了

?

用鎖來限制

?

?

針對Servlet的線程安全問題,Sun公司是提供有解決方案的:讓Servlet去實(shí)現(xiàn)一個SingleThreadModel接口,如果某個Servlet實(shí)現(xiàn)了SingleThreadModel接口,那么Servlet引擎將以單線程模式來調(diào)用其service方法。
  查看Sevlet的API可以看到,SingleThreadModel接口中沒有定義任何方法和常量,在Java中,把沒有定義任何方法和常量的接口稱之為標(biāo)記接口,經(jīng)常看到的一個最典型的標(biāo)記接口就是"Serializable",這個接口也是沒有定義任何方法和常量的,標(biāo)記接口在Java中有什么用呢?主要作用就是給某個對象打上一個標(biāo)志,告訴JVM,這個對象可以做什么,比如實(shí)現(xiàn)了"Serializable"接口的類的對象就可以被序列化,還有一個"Cloneable"接口,這個也是一個標(biāo)記接口,在默認(rèn)情況下,Java中的對象是不允許被克隆的,就像現(xiàn)實(shí)生活中的人一樣,不允許克隆,但是只要實(shí)現(xiàn)了"Cloneable"接口,那么對象就可以被克隆了。

  讓Servlet實(shí)現(xiàn)了SingleThreadModel接口,只要在Servlet類的定義中增加實(shí)現(xiàn)SingleThreadModel接口的聲明即可。 ?
  對于實(shí)現(xiàn)了SingleThreadModel接口的Servlet,Servlet引擎仍然支持對該Servlet的多線程并發(fā)訪問,其采用的方式是產(chǎn)生多個Servlet實(shí)例對象,并發(fā)的每個線程分別調(diào)用一個獨(dú)立的Servlet實(shí)例對象
  實(shí)現(xiàn)SingleThreadModel接口并不能真正解決Servlet的線程安全問題,因?yàn)镾ervlet引擎會創(chuàng)建多個Servlet實(shí)例對象,而真正意義上解決多線程安全問題是指一個Servlet實(shí)例對象被多個線程同時調(diào)用的問題。事實(shí)上,在Servlet API 2.4中,已經(jīng)將SingleThreadModel標(biāo)記為Deprecated(過時的)。

?

?

?

ServletConfig?配置Servlet初始化參數(shù)

?

當(dāng)servlet配置了初始化參數(shù)后,web容器在創(chuàng)建servlet實(shí)例對象時,會自動將這些初始化參數(shù)封裝到ServletConfig對象中,并在調(diào)用servlet的init方法時,將ServletConfig對象傳遞給servlet。進(jìn)而,我們通過ServletConfig對象就可以得到當(dāng)前servlet的初始化參數(shù)信息。

?

?

ServletContext對象(多個Servlet通過ServletContext對象實(shí)現(xiàn)數(shù)據(jù)共享)

范例:ServletContextDemo1和ServletContextDemo2通過ServletContext對象實(shí)現(xiàn)數(shù)據(jù)共享

?

?

先運(yùn)行ServletContextDemo1,將數(shù)據(jù)data存儲到ServletContext對象中,然后運(yùn)行ServletContextDemo2就可以從ServletContext對象中取出數(shù)據(jù)了,這樣就實(shí)現(xiàn)了數(shù)據(jù)共享

?

獲取WEB應(yīng)用的初始化參數(shù)

?

?

?

用servletContext實(shí)現(xiàn)請求轉(zhuǎn)發(fā)

訪問的是ServletContextDemo4,瀏覽器顯示的卻是ServletContextDemo5的內(nèi)容,這就是使用ServletContext實(shí)現(xiàn)了請求轉(zhuǎn)發(fā)

?

?

利用ServletContext對象讀取資源文件

InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db1.properties");

Properties prop = new Properties();

prop.load(in);

String driver = prop.getProperty("driver");

?

總結(jié)

以上是生活随笔為你收集整理的Servlet简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。