自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java網(wǎng)絡(luò)編程基本功之Servlet與Servlet容器

開發(fā) 后端
使用 Java 的 Socket 套接字進(jìn)行編程,去處理客戶端來的 tcp 請求,經(jīng)過編解碼處理讀取請求體,獲取請求行,然后找到請求行對應(yīng)的處理邏輯步入服務(wù)器的處理中,處理完畢把對應(yīng)的結(jié)果返回給當(dāng)前的 Socket 鏈接,響應(yīng)完畢,關(guān)閉 Socket。

Servlet與Servlet容器關(guān)系

Servlet

比較這兩個的區(qū)別, 就得先搞清楚Servlet 的含義, Servlet (/?s?rvlit/ ) 翻譯成中文就是小型應(yīng)用程序或者小服務(wù)程序, 與之相類似的是Server (/?s??rv?r/), 翻譯過來是服務(wù)器的意思, 可見這二者承擔(dān)類似的功能,但是Servlet更輕量。

web開發(fā)的本質(zhì)就一句話:客戶端和服務(wù)器交換數(shù)據(jù)。于是使用 Java 的 Socket 套接字進(jìn)行編程,去處理客戶端來的 tcp 請求,經(jīng)過編解碼處理讀取請求體,獲取請求行,然后找到請求行對應(yīng)的處理邏輯步入服務(wù)器的處理中,處理完畢把對應(yīng)的結(jié)果返回給當(dāng)前的 Socket 鏈接,響應(yīng)完畢,關(guān)閉 Socket。

上述過程中, 建立連接、傳輸數(shù)據(jù)、關(guān)閉連接等過程是tomcat容器幫你做了這些事情, 而拿到請求行之后去找對應(yīng)的 url 路由,這一部分是誰做的呢?是Servlet ! 簡單來說Servlet就是一段處理 web 請求的邏輯。

具體來說Servlet具有以下幾個特點:

  1. Servlet是用Java編寫的Server端程序,它與協(xié)議和平臺無關(guān)。
  2. Servlet運行于Java-enabled Web Server中。
  3. Java Servlet可以動態(tài)地擴(kuò)展Server的能力,并采用請求-響應(yīng)模式提供Web服務(wù)。
  4. 最早支持Servlet技術(shù)的是JavaSoft的Java Web Server。
  5. 此后,一些其它的基于Java的Web Server開始支持標(biāo)準(zhǔn)的Servlet API。
  6. Servlet的主要功能在于交互式地瀏覽和修改數(shù)據(jù),生成動態(tài)Web內(nèi)容。

上面六點中,最需要被記住的是Servlet可以動態(tài)地擴(kuò)展Server的能力,并采用請求-響應(yīng)模式提供Web服務(wù)。

JDK中的Servlet是一個接口:

public interface Servlet { 
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public String getServletInfo();
public void destroy();
}

可以看到Servlet 是一個接口, 規(guī)定了請求從容器到達(dá) web 服務(wù)端的規(guī)范,詳細(xì)內(nèi)容在后面的Servlet生命周期中詳細(xì)梳理,這兒簡單概括三個重要步驟是:

  1. init():初始化請求的時候要做什么。
  2. service():拿到請求的時候要做什么。
  3. destory():處理完請求銷毀的時候要做什么。

所有實現(xiàn) Servlet 的實現(xiàn)方都是在這個規(guī)范的基礎(chǔ)上進(jìn)行開發(fā)。那么 Servlet 中的數(shù)據(jù)是從哪里來的呢?答案就是 Servlet 容器。容器才是真正與客戶端打交道的那一方。一個容器中 Servlet 可以有多個, 常見的Servlet容器Tomcat,它監(jiān)聽了客戶端的請求端口,根據(jù)請求行信息確定將請求交給哪個Servlet 處理,找到處理的Servlet之后,調(diào)用該Servlet的 service() 方法,處理完畢將對應(yīng)的處理結(jié)果包裝成ServletResponse 對象返回給客戶端。

Servlet容器

現(xiàn)在講講Servlet容器, 前面說過看Servlet只是一個接口或者說是規(guī)范, 那么就勢必有具體實現(xiàn), 而Servlet具體實現(xiàn)或者說包裝器是Wrapper, 直接管理Wrapper的容器就是Context, 一個 Context 對應(yīng)一個 Web 工程, 也就是說Context 容器如何運行將直接影響 Servlet 的工作。

由圖可以知道, Tomcat底層是Context, Context負(fù)責(zé)管理Servlet包裝類Wrapper。

下面創(chuàng)建一個實例對象并調(diào)用 start 方法就可以很容易啟動 Tomcat,我們還可以通過這個對象來增加和修改 Tomcat 的配置參數(shù),如可以動態(tài)增加 Context、Servlet 等。我們就選擇 Tomcat7 自帶的 examples Web 工程,并看看它是如何加到這個 Context 容器中的。

//給 Tomcat 增加一個 Web 工程:
Tomcat tomcat = getTomcatInstance();
File appDir = new File(getBuildDirectory(), "webapps/examples");
tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
tomcat.start();
ByteChunk res = getUrl("http://localhost:" + getPort() +
"/examples/servlets/servlet/HelloWorldExample");
assertTrue(res.toString().indexOf("<h1>Hello World!</h1>") > 0);

上述代碼是創(chuàng)建一個 Tomcat 實例并新增一個 Web 應(yīng)用,然后啟動 Tomcat 并調(diào)用其中的一個 HelloWorldExample Servlet,看有沒有正確返回預(yù)期的數(shù)據(jù)。

//Tomcat 的 addWebapp 方法的代碼如下:
public Context addWebapp(Host host, String url, String path) {
silence(url);
Context ctx = new StandardContext();
ctx.setPath( url );
ctx.setDocBase(path);
if (defaultRealm == null) {
initSimpleAuth();
}
ctx.setRealm(defaultRealm);
ctx.addLifecycleListener(new DefaultWebXmlListener());
ContextConfig ctxCfg = new ContextConfig();
ctx.addLifecycleListener(ctxCfg);
ctxCfg.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML");
if (host == null) {
getHost().addChild(ctx);
} else {
host.addChild(ctx);
}
return ctx;
}

添加一個 Web 應(yīng)用時將會創(chuàng)建一個 StandardContext 容器,并且給這個 Context 容器設(shè)置必要的參數(shù)(url 代表這個應(yīng)用在 Tomcat 中的訪問路徑; path 代表這個應(yīng)用實際的物理路徑) 其中最重要的一個配置是 ContextConfig,【ContextConfig監(jiān)聽器】繼承了 【LifecycleListener 監(jiān)聽器接口】,它是在調(diào)用清單 2 時被加入到 StandardContext 容器中。 當(dāng) Context 容器初始化狀態(tài)設(shè)為 init 時,添加在 Context 容器的 Listener 將會被調(diào)用?!綜ontextConfig監(jiān)聽器】將會負(fù)責(zé)整個 Web 應(yīng)用配置文件的解析工作。最后將這個 Context 容器加到父容器 Host 中。

Servlet生命周期

Servlet生命周期分為四個部分: 實例化==>初始化==>執(zhí)行處理==>銷毀。

實例化

new , 服務(wù)器第一次被訪問時,加載一個Servlet容器,只會被加載一次。

初始化

init:創(chuàng)建完Servlet容器后,會調(diào)用僅執(zhí)行一次的init()初始化方法,用于初始化Servlet對象,無論多少臺客戶端在服務(wù)器運行期間訪問都不會再執(zhí)行init()方法。

可以在繼承的GenericServlet這個抽象類中看到初始化方法:

public void init() throws ServletException {
}

而在我們的Servlet類中應(yīng)繼承調(diào)用該方法:

public void init() throws ServletException {
super.init();
}

創(chuàng)建Servlet對象的時機(jī):

  1. Servlet容器啟動時:讀取web.xml配置文件中的信息,構(gòu)造指定的Servlet對象,創(chuàng)建ServletConfig對象,同時將ServletConfig對象作為參數(shù)來調(diào)用Servlet對象的init方法。
  2. 在Servlet容器啟動后:客戶首次向Servlet發(fā)出請求,Servlet容器會判斷內(nèi)存中是否存在指定的Servlet對象,如果沒有則創(chuàng)建它,然后根據(jù)客戶的請求創(chuàng)建HttpRequest、HttpResponse對象,從而調(diào)用Servlet 對象的service方法。
  3. Servlet:Servlet容器在啟動時自動創(chuàng)建Servlet,這是由在web.xml文件中為Servlet設(shè)置的屬性決定的。從中我們也能看到同一個類型的Servlet對象在Servlet容器中以單例的形式存在。

執(zhí)行處理

執(zhí)行處理——service()方法

它是Servlet的核心,負(fù)責(zé)響應(yīng)客戶的請求。每當(dāng)一個客戶請求一個HttpServlet對象,該對象的Service()方法就要調(diào)用,而且傳遞給這個方法一個“請求”(ServletRequest)對象和一個“響應(yīng)”(ServletResponse)對象作為參數(shù)。在HttpServlet中已存在Service()方法。默認(rèn)的服務(wù)功能是調(diào)用與HTTP請求的方法相應(yīng)的do功能。

HttpServlet的抽象類提供了doGet()、doPost()……等方法。對應(yīng)了request請求的發(fā)送方法,與之相匹配:

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}

上面是操作性最高的部分。

銷毀

銷毀——destroy:在服務(wù)器關(guān)閉或重啟時,Servlet會調(diào)用destroy方法來銷毀,將Servlet容器標(biāo)記為垃圾文件,讓GC做回收處理。我們編寫的Servlet是調(diào)用了GenericServlet抽象類的destroy方法:

@Override
public void destroy() {
super.destroy();
}

Servlet工作原理

1、首先簡單解釋一下Servlet接收和響應(yīng)客戶請求的過程:

客戶發(fā)送一個請求,Servlet是調(diào)用service()方法對請求進(jìn)行響應(yīng),service()方法中對請求的方式進(jìn)行了匹配。選擇調(diào)用doGet,doPost等這些方法,然后再進(jìn)入對應(yīng)的方法中調(diào)用邏輯層的方法,實現(xiàn)對客戶的響應(yīng)。在Servlet接口和GenericServlet中是沒有doGet()、doPost()等等這些方法的,HttpServlet中定義了這些方法,但是都是返回error信息,所以,我們每次定義一個Servlet的時候,都必須實現(xiàn)doGet或doPost等這些方法。

2、每一個自定義的Servlet都必須實現(xiàn)Servlet的接口,Servlet接口中定義了五個方法,其中比較重要的三個方法涉及到Servlet的生命周期,分別是上文提到的init(),service(),destroy()方法。GenericServlet是一個通用的,不特定于任何協(xié)議的Servlet,它實現(xiàn)了Servlet接口。而HttpServlet繼承于GenericServlet,因此HttpServlet也實現(xiàn)了Servlet接口。所以我們定義Servlet的時候只需要繼承HttpServlet即可。

3、Servlet接口和GenericServlet是不特定于任何協(xié)議的,而HttpServlet是特定于HTTP協(xié)議的類,所以HttpServlet中實現(xiàn)了service()方法,并將請求ServletRequest、ServletResponse 強(qiáng)轉(zhuǎn)為HttpRequest 和 HttpResponse。

4、另外,Servlet是單例模式,線程是不安全的,因此在service()方法中盡量不要操作全局變量。但實際上,可以通過使用session和application來代替全局變量,只是會加大服務(wù)器負(fù)載。

Servlet處理請求的過程

  1. 客戶端發(fā)送請求給服務(wù)器。
  2. 容器根據(jù)請求及web.xml判斷對應(yīng)的Servlet是否存在,如果不存在則返回404。
  3. 容器根據(jù)請求及web.xml判斷對應(yīng)的Servlet是否已經(jīng)被實例化,若是相應(yīng)的Servlet沒有被實例化,則容器將會加載相應(yīng)的Servlet到Java虛擬機(jī)并實例化。
  4. 調(diào)用實例對象的service()方法,并開啟一個新的線程去執(zhí)行相關(guān)處理。調(diào)用servce方法,判斷是調(diào)用doGet方法還是doPost方法。
  5. 業(yè)務(wù)完成后響應(yīng)相關(guān)的頁面發(fā)送給客戶端。
責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2014-11-20 14:39:12

網(wǎng)絡(luò)傳輸

2009-07-08 11:17:10

Servlet容器Servlet Con

2009-07-09 11:27:59

Servlet容器

2009-07-06 14:05:50

Servlet編程Servlet顯示圖片

2015-01-15 09:21:24

TCP窗口

2009-07-03 16:53:11

Servlet容器

2009-07-09 13:45:06

Servlet基本結(jié)構(gòu)

2017-04-12 10:40:34

公有云

2011-07-22 16:43:37

java

2009-07-09 15:30:53

Servlet容器會話跟蹤

2009-07-06 18:24:56

Servlet實例

2009-07-08 14:01:47

Servlet容器

2009-07-07 16:23:05

Servlet容器

2009-07-08 14:22:36

Servlet容器匹配過程

2010-09-26 08:56:10

Oracle

2010-05-27 15:05:23

ServletJava

2024-11-01 08:34:18

Spring配置@Bean

2009-07-07 17:23:08

Java Servle

2020-07-21 14:35:44

Servlet容器ApacheTomcat

2009-07-08 09:35:53

Java ServleServlet 3.0
點贊
收藏

51CTO技術(shù)棧公眾號