国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

Servlet簡介(一)

2019-11-18 16:21:39
字體:
來源:轉載
供稿:網友

  目錄:

1. 關于Servlets
* 舉例
* 結構介紹
* Lifecycle
2. 怎樣編寫一個servlet程序
* 客戶端的交互性
* Lifecycle 方法
* 提供有關Servlet的信息
3. 怎樣用servletrunner運行一個Servlet程序

關于Servlets

Servlets是java 2.0中新增的一個全新功能。

JAVA Servlets 是運行在請求/面向請求服務器上的模塊,比如一個Java-enabled web 服務器, 和類似這樣的延伸場合. 例如, 一個servlet可以從一個Html訂單表中獲取數據然后用一些商業上的算法來更新公司相應的訂單數據庫

也就是說:servlet能夠象CGI腳本一樣擴展WEB服務器功能,但是servlet占用很少密集資源,有很多用CGI腳本編制的一些站點由于訪問量劇增,性能迅速下降,這是CGI腳本一個缺點,有關CGI腳本概念請參照本齋"CGI入門學習" 。同時由于servlet是用java編寫的,因此是跨平臺的。
實際servlet是電子商務真正的開始。

Servlet API, 是用來寫servlet的, 編寫servlet是已沒有CGI腳本那樣諸如關心一個servlet是這樣被裝載, servlet運行的服務器環境是什么, 或者用來傳輸數據的協議是什么等等,這樣servlets就可以融合在不同的web服務器中.

Servlet可以相當有效地替代CGI腳本: 它可以方便地產生容易編寫而且運行快的動態文本. 可以很方便的調試尋找出程序問題. Servlet程序是用Java Servlet API開發的, a standard Java extension. 但不是Java核心框架的一部分,可以作為通用的附加產品包被商家購買使用.
舉例

下面是一些servlet應用范圍:

* 用于處理HTML表單通過HTTPS產生POSTed數據, 包括買賣訂單或信用卡數據. 因此servlet可以成為訂單處理系統的一部分, 和產品存貨數據庫一道工作,也許可以用在在線支付系統上.
* 允許人們之間的合作. 一個servlet能并發處理多個請求; 他們可以使用在諸如在線會議這樣的同步請求支持系統.
* 轉送請求. Servlet可以轉送請求給其他的服務器和servlets. 這就允許在鏡象同樣內容的幾個服務器之間平衡負載. 按照任務類型或組織范圍,可以允許被用來在幾個服務器中劃分邏輯上的服務器.
* servlet 編寫者們可以定義彼此之間共同工作的激活代理,每個代理者是一個servlet, 而且代理者能夠在他們之間傳送數據.

Servlet 結構總視

在具體掌握servlet之前,須對java語言有所了解。下面是基于您了解java基礎上的,在Servlet API中最重要的是Servlet interface. 所有的servlets implement(執行)這個interface, 方式多種:或者是直接的,或者通過extending 這個class執行它,如 HttpServlet. 這個Servlet interface 提供安排servlet與客戶端聯系的方法. Servlet 編寫者可以在他們開發servlet程序時提供更多一些或所有的這樣方法.

當一個servlet接收來自客戶端的調用請求, 它接收兩個對象: 一個是ServletRequest,另外一個是ServletResponse. 這個ServletRequest class 概括從客戶端到服務器之間的聯系, 而 ServletResponse class 概括從servlet返回客戶端的聯系.

ServletRequest interface 可以獲取到這樣一些信息如由客戶端傳送的闡述名稱,客戶端正在使用的協議, 產生請求并且接收請求的服務器遠端主機名. 它也提供獲取數據流的servlet, ServletInputStream, 這些數據是客戶端引用中使用HTTP POST 和 PUT 方法遞交的. 一個ServletRequest的子類可以讓servlet獲取更多的協議特性數據. 例如: HttpServletRequest 包含獲取HTTP-specific頭部信息的方法.

ServletResponse interface 給出相應客戶端的servlet方法. 它允許servlet設置內容長度和回應的mime類型, 并且提供輸出流, ServletOutputStream, 通過編寫者可以發回相應數據. ServletResponse子類可以給出更多PRotocol-specific容量的信息。 例如: HttpServletResponse 包含允許servlet操作HTTP-specific頭部信息的方法.

上面有關classes 和 interfaces描述構成了一個基本的Servlet框架. HTTP servlets有一些附加的可以提供session-tracking capabilities的方法. servlet編寫者可以用這些API在有他人操作時維護servlet與客戶端之間的狀態.
Servlet Lifecycle

服務器裝載運行servlets:接收來自客戶端的多個請求并且返回數據給客戶端. 然后在刪除移開servlets. 這就是servlets lifecycle過程. 下面詳細描述:

當一個服務器裝載servlet時, 它運行servlet的 init 方法. 這個方法不能反復調用,一旦調用就是再裝載servlet. 直到服務器調用 destroy 方法卸載servlet后才能再調用.

在服務器裝載初始化后servlet, servlet就能夠處理客戶端的請求. 用service 方法做到這一點. 每個客戶端請求有它自己service方法: 這些方法接收客戶端請求, 并且發回相應的響應.

Servlets能同時運行多個service. 這是很重要的, 這樣, service方法可以按一個thread-safe 樣式編寫. 如:service方法更新servlet對象中的一個字段field, 這個字段可以同時存取的. 假如某個服務器不能同時并發運行service方法,也可以用SingleThreadModel interface. 這個 interface 保證不會有兩個以上的線程threads并發運行.

Servlets一直運行到他們被服務器卸載。
在servlet的lifecycle中, 編寫一個thread-safe編碼以卸載servlet是很重要的。
編寫Servlet

Servlets 執行 javax.servlet.Servlet interface. 當servlet編寫者可以通過直接implement interface開發servlet, 但這樣通常沒有必要. 因為大多數servlet是針對用HTTP協議的web服務器, 這樣最通用開發servlet辦法是用 javax.servlet.http.HttpServlet 內.

HttpServlet 類通過extend GenericServlet基類執行 Servlet interface, 提供了處理HTTP協議的功能. 他的service方法支持標準HTTP/1.1請求.

一般地, 用HttpServlet指定的類編寫的servlets可以多線程地并發運行service方法.

與客戶端的交互性

Servlet編寫者注意HttpServlet類有幾個欠缺的方法,你可以自己定義方法中內容,但是必須使用這些方法名稱以使servlet知道你想做什么,

* doGet, 用于處理 GET、有條件的GET 和頭部 HEAD請求
* doPost, 用戶處理 POST 請求
* doPut, 用于處理 PUT 請求
* doDelete, 用于處理 DELETE請求

HttpServlet的service方法, 一般地, 當它接收到一個OPTIONS請求時,會調用doOptions 方法, 當接收一個TRACE請求是調用doTrace . doOptions缺省執行方式是自動決定什么樣的HTTP被選擇并且返回哪個信息.

在你使用這些方法時,必須帶兩個闡述. 第一個包含來自客戶端的數據HttpServletRequest. 第二個參數包含客戶端的響應HttpServletResponse. 在下例中是這樣的情況.

一個HttpServletRequest對象提供到達HTTP 頭部數據, 也允許你獲取客戶端的數據. 怎樣獲取這些數據取決于HTTP端請求方法.

* 不管任何HTTP方式, 你可以用 getParameterValues 方法, 這個用來返回特定名稱的參數值.
* 對于用 HTTP GET 請求的方式, 這個 getQueryString 方法將會返回一個可以用來解剖分析的.
* 對于用HTTP POST, PUT, 和 DELETE請求的方式, 你有兩種方法可以選擇. 如果是文本數據,你能通過getReader方法用BufferedReader獲取 ; 如果是二進制數據, 能通過getReader 方法用 ServletInputStream獲取.

為了響應客戶端, 一個HttpServletResponse對象提供返回數據給用戶的兩個方法. 你可以用getWriter 方法返回,或者 getOutputStream 方法以輸出流返回. 你應該用getWriter返回文本數據,而用getOutputStream返回二進制數據.

在使用Writer 或 OutputStream之前, HTTP 頭部應該先被設置. HttpServletResponse內提供這樣一個方法,之后可以用writer 或 outputstream 將響應主體部分發回用戶. 完成后要關閉 writer 或 output stream以便讓服務器知道響應已經完畢.
一個HTTP Servlet處理GET和HEAD方法的例子

public class SimpleServlet extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
// 首先設置頭部
res.setContentType("text/html");

// 用 writer方法返回響應數據
PrintWriter out = res.getWriter();
out.println("<HEAD><TITLE> SimpleServlet Output</TITLE></HEAD><BODY>");
out.println("<h1> SimpleServlet Output </h1>");
out.println("<P>This is output is from SimpleServlet.");
out.println("</BODY>");
out.close();
}

public String getServletInfo() {
return "A simple servlet";
}

}

這個例子完整地現實了一個servlet.
一個HTTP Servlet處理POST方式的例子

這里是個用HTML帶POST表單的例子:

<html>
<head><title>JdcSurvey</title></head>
<body>
<form action=http://demo:8080/servlet/survey method=POST>
<input type=hidden name=survey value=Survey01Results>

<BR><BR>How Many Employees in your Company?<BR>
<BR>1-100<input type=radio name=employee value=1-100>
<BR>100-200<input type=radio name=employee value=100-200>
<BR>200-300<input type=radio name=employee value=200-300>
<BR>300-400<input type=radio name=employee value=300-400>
<BR>500-more<input type=radio name=employee value=500-more>

<BR><BR>General Comments?<BR>
<BR><input type=text name=comment>

<BR><BR>What IDEs do you use?<BR>
<BR>JavaWorkShop<input type=checkbox name=ide value=JavaWorkShop>
<BR>J++<input type=checkbox name=ide value=J++>
<BR>Cafe'<input type=checkbox name=ide value=Cafe'>

<BR><BR><input type=submit><input type=reset>
</form>
</body>
</html>

這里的servlet將表單數據寫入一個文件,并且用一個thank you信息響應用戶. 這里servlet的方法,如下例:

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
// 首先設置響應的 "content type" 頭部
res.setContentType("text/html");

//得到響應的 PrintWriter以返回文本給客戶端.
PrintWriter toClient = res.getWriter();

try {
//打開一個文件寫入Survey的結果.
String surveyName = req.getParameterValues("survey")[0];
FileWriter resultsFile = new FileWriter(resultsDir
+ System.getProperty("file.separator")
+ surveyName + ".txt", true);
PrintWriter toFile = new PrintWriter(resultsFile);

// 從客戶端得到表單數據 & 存貯在這個文件中
toFile.println("<BEGIN>");
Enumeration values = req.getParameterNames();
while(values
}
toFile.println("<END>");

//關閉文件.
resultsFile.close();

// 用一個thank you返回客戶端
toClient.println("<html>");
toClient.println("<title>Thank you!</title>");
toClient.println("Thank you for partictoClient.println("</html>");

} catch(IOException e) {
e.printStackTrace();
toClient.println(
"A problem occured while recording your answers. "
+ "Please try again.");
}

// 關閉writer; 響應完成.
toClient.close();
}

這個doPost方法是用getParameterNames和getParameterValues方法來從表單中獲取數據的. 因為它返回文本給客戶端, doPost 將調用 getWriter 方法. 在寫入響應主體部分之前,它設置了響應頭部字段的設置, 但響應完成后,關閉.
Lifecycle 方法
重編Init 初始化方法

在初始化過程中, servlet應當準備好它要安排的一些資源, 以便這個servlet能夠接收請求,做到這些可以不用考慮多線程, 因為在servlet初始化是只能是單進程的。 一旦初始化方法完成, servlet就能接收客戶端的請求。 當然如果初始化不能成功,這個方法會扔出throw UnavailableException解釋的.

初始化方法使用ServletConfig 對象作為參數. 這個方法應該保存這個對象, 以便它能有方法getServletConfig返回. 最簡單的辦法是,搞出一個新類,他的初始化方法數調用super.init. 如果確實這樣做, 你就應當自己保存ServletConfig對象, 并且自己重編getServletConfig 方法以便它能從新的位置得到對象.

下面是個初始化方法的例子. 它是來自Survey Servlet的初始化方法, 從一個表單接收輸入然后存儲到文件中,為了存儲survey信息, 它需要一個目錄. 它以初始化參數接收這個目錄.

public void init(ServletConfig config)
throws ServletException
{
super.init(config);

//獲取目錄
resultsDir = getInitParameter("resultsDir");

//如果沒有目錄, 不處理客戶端
if (resultsDir == null) {
throw new UnavailableException (this,
"Not given a Directory to write survey results!");
}
}

這里的初始化方法調用super.init 方法來管理安排ServletConfig對象. 這個初始化方法也設置了一個字段: resultsDir, 作為初始化參數提供的目錄名. 如果沒有目錄名被提供, 這個 servlet扔出一個不適用的解釋. 如果初始化方法成功完成,servlet將能處理客戶端請求
初始化參數

初始化參數的規定是一個服務器方面的規定。

如果初始化參數被規定, 都可以用同樣的方法得到: 用 getInitParameter 方法. 這個方法將參數名作為自己的參數項.
重編Destroy 方法

當服務器卸載一個servlet, 它將調用servlet的destroy方法. 這個destroy方法是與初始化方法相反,同時從內存中釋放servlet.

并不是所有的調用了初始化init方法是也必須調用destroy方法.

對于大多數的servlets, 一些初始化的工作必須反做的. 如, 假設有一個servlet,它在初始化時打開一個數據庫連接,他的destroy 方法如下顯示:需要關閉這個連接的

/**
* 關閉數據庫連接
*/
public void destroy() {
try {
con.close();
} catch (SQLException e) {
while(e != null) {
log("SQLException: " + e.getSQLState() + '/t' +
e.getMessage() + '/t' +
e.getErrorCode() + '/t');
e = e.getNextException();
}
} catch (Exception e) {
e.printStackTrace();
}
}

關于一個Servlet中斷涉及的多線程

但一個服務器卸載一個servlet, 它會在所有的service已經完成后調用destroy. 如果你的操作運行需要很長時間, 但destroy 被調用時還有線程在運行. 這個servlet編寫者有責任確保所有的線程都已經完成;

長時間運行響應客戶端請求的那些servlet應當保留當前有多少方法在運行的記錄. 他的 long-running 方法應當周期性地輪詢以確保他們能夠繼續運行下去. 如果servlet被destroy方法調用, 那么這個long-running 方法如果必要必須停止工作或清除.

舉例, 變量serviceCounter用來統計有多少service方法在運行, 變量shuttingDown顯示這個servlet是否被destory. 每個變量有它自己的獲取方法:

public ShutdownExample extends HttpServlet {
private int serviceCounter = 0;
private Boolean shuttingDown;
...
// serviceCounter
protected synchronized void enteringServiceMethod() {
serviceCounter++;
}
protected synchronized void leavingServiceMethod() {
serviceCounter--;
}
protected synchronized int numServices() {
return serviceCounter;
}
//shuttingDown
protected setShuttingDown(Boolean flag) {
shuttingDown = flag;
}
protected Boolean isShuttingDown() {
return shuttingDown;
}
}

這個service方法每次在它進入時要增加,而在它返回退出時要減少:

protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
enteringServiceMethod();
try {
super.service(req, resp);
} finally {
leavingServiceMethod();
}
}

destroy方法應當檢查serviceCounter, 如果存在長時間方式運行的話, 設置變量shuttingDown . 這個變量將會讓那個正在處理請求的線程知道:該結束了,關閉吧! destroy 方法應當等待這幾個service 方法完成, 這樣就是一個清楚的關閉過程了.

public void destroy() {
/* 檢查是否有線程在運行,如果存在,告訴他們stop. */
if (numServices() > 0) {
setShuttingDown(true);
}

/* 等待他們stop. */
while(numService() > 0) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e) {
}
}
}

long-running 方法如必要應當檢查這個變量,并且解釋他們的工作:

public void doPost( catch (InterruptedException e) {
}
}
}

提供關于Servlet的信息

/**
* This is a simple example of an HTTP Servlet. It responds to the GET
* and HEAD methods of the HTTP protocol.
*/
public class SimpleServlet extends HttpServlet {

...

public String getServletInfo() {
return "A simple servlet";
}
}進入討論組討論。

(出處:http://m.survivalescaperooms.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武宁县| 延安市| 永德县| 滨海县| 太仓市| 镇沅| 万载县| 承德市| 崇阳县| 邮箱| 青田县| 奇台县| 宁夏| 黄石市| 泾川县| 龙门县| 浦县| 合江县| 彩票| 西昌市| 丹巴县| 泰兴市| 历史| 汝南县| 白玉县| 横山县| 长兴县| 明光市| 台安县| 当涂县| 萍乡市| 高安市| 清原| 泸西县| 陆丰市| 清流县| 西吉县| 新巴尔虎左旗| 玛纳斯县| 灵璧县| 开原市|