亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

SERVLETS簡介

2019-11-18 15:08:35
字體:
來源:轉載
供稿:網友

  □ 關于Servlets
□ 舉例
□ 結構介紹
□ Lifecycle
□ 怎樣編寫一個servlet程序
□ 客戶端的交互性
□ Lifecycle 方法
□ 提供有關Servlet的信息
□ 怎樣用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.hasMoreElements()) {
        String name = (String)values.nextElement();
        String value = req.getParameterValues(name)[0];
        if(name.compareTo("submit") != 0) {
          toFile.println(name + ": " + value);
        }
      }
      toFile.println("<END>");

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

      // 用一個thank you返回客戶端
      toClient.println("<html>");
      toClient.println("<title>Thank you!</title>");
      toClient.println("Thank you for partic      toClient.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(...) {
    ...
    for(i = 0; ((i < lotsOfStuffToDo) && !isShuttingDown()); i++) {
      try {
        partOfLongRunning
Operation(i);
      } 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";
  }
}

怎樣用servletrunner來運行Servlet

一旦你寫好你的 servlet, 可以運行在很多web服務器上, 或者在 servletrunner里.

屬性
屬性是一對key-value, 用作配置, 創建, 和servlet的初始化. 如, servlet.phone.code=PhoneServlet 的key 是 servlet.phone.code,他的value 是 PhoneServlet.

一個servlet有兩個屬性. 一個是servlet.name.code, 他的值是servlet的類名. 另一個是servlet.name.initargs, 他的值是保存獲取servlet的初始化參數 

用 code 屬性

servlet.name.code 屬性用它類的名命名你的servlet. 假如你的servlet使用初始化參數,這個屬性就必須的. 它答應服務器聯合servlet 對象和他的初始化參數項,他們兩有同樣的名字name. 即使你的servlet沒有使用初始化參數,也推薦使用這個屬性,以便客戶端能用它自己的名字達到servlet. 

Initargs 屬性的語法

servlet.name.initArgs 屬性的值是保存初始化參數的值. 相應的一個參數的語法是:parameterName=parameterValue. 舉例一個 phone servlet參數象下面:

servlet.phone.initArgs=phonelis

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲最大中文字幕| 自拍亚洲一区欧美另类| 中文字幕久热精品在线视频| 国产精品网红直播| 91精品免费视频| 欧美一级视频一区二区| 在线精品高清中文字幕| 伊人久久男人天堂| 亚洲日本欧美日韩高观看| 亚洲欧美日韩天堂一区二区| 国产午夜精品一区二区三区| 成人网址在线观看| 亚洲网站在线看| 亚洲片国产一区一级在线观看| 成人国产精品一区| 日韩一级黄色av| 欧美综合在线观看| 成人欧美一区二区三区在线湿哒哒| 国产视频久久网| 色噜噜狠狠色综合网图区| 欧美日韩色婷婷| 国产精品白嫩美女在线观看| 欧美精品videosex性欧美| 亚洲成人久久电影| 国产美女搞久久| 亚洲人成网7777777国产| 自拍偷拍亚洲欧美| 97在线免费观看视频| 国产成人短视频| 久久偷看各类女兵18女厕嘘嘘| 欧美一级淫片videoshd| 欧美日本啪啪无遮挡网站| 日韩欧美黄色动漫| 久久av在线播放| 欧美与黑人午夜性猛交久久久| 国产精品偷伦免费视频观看的| 久久久久久久香蕉网| 亚洲精品短视频| 日韩免费不卡av| 国产精品久久久久久久久免费| 日韩中文字幕在线视频| 亚洲一区二区黄| 国产极品jizzhd欧美| 亚洲精品电影久久久| 欧美国产精品日韩| 欧美电影免费观看| 国产91色在线|| 色综合久久88| 欧美在线视频网| 亚洲人成伊人成综合网久久久| 中文国产成人精品久久一| 亚洲精品免费在线视频| 81精品国产乱码久久久久久| 亚洲精品欧美一区二区三区| 亚洲天堂av电影| 欧美色视频日本高清在线观看| 国产主播喷水一区二区| 777国产偷窥盗摄精品视频| 国产激情综合五月久久| 日本亚洲欧洲色α| 91精品国产高清久久久久久91| 亚洲高清一区二| 欧美在线视频a| 欧美一区三区三区高中清蜜桃| 久久99久国产精品黄毛片入口| 欧美大片欧美激情性色a∨久久| 国产精品美女主播在线观看纯欲| 亚洲国产精品久久久| 爽爽爽爽爽爽爽成人免费观看| 国产精品丝袜高跟| 欧美日韩一区二区精品| 国产69精品久久久| 国产精品美女久久久久久免费| 欧美成人免费一级人片100| 69视频在线播放| 91国偷自产一区二区三区的观看方式| 国产精品久久久久av免费| 日韩经典中文字幕在线观看| 欧美人交a欧美精品| 韩日欧美一区二区| 高跟丝袜一区二区三区| 中文字幕亚洲字幕| 欧美成人激情视频免费观看| 精品久久久久久久久久久| 精品无码久久久久久国产| 久久精品成人欧美大片古装| 欧美电影电视剧在线观看| 亚洲综合中文字幕68页| 欧美日韩中文字幕| 久久九九精品99国产精品| 国产精品扒开腿做爽爽爽视频| 欧美激情第三页| 欧美性极品xxxx娇小| 国产女人精品视频| 日韩av在线直播| 国产精品福利片| 久久国产精品免费视频| 亚洲国产第一页| 国产精品老女人精品视频| 26uuu亚洲国产精品| 欧美一级大片在线观看| 亚洲视频999| 麻豆乱码国产一区二区三区| …久久精品99久久香蕉国产| 亚洲一区二区久久久| 亚洲自拍在线观看| 国产在线视频一区| 中文字幕视频一区二区在线有码| 国模视频一区二区三区| 欧美一级电影免费在线观看| 69**夜色精品国产69乱| 68精品国产免费久久久久久婷婷| 亚洲黄页网在线观看| 欧美中文字幕视频在线观看| 久久五月天色综合| 国产精品a久久久久久| 亚洲国产精品电影在线观看| 成人激情视频在线播放| 精品视频一区在线视频| 日韩国产精品一区| 日韩电影免费观看在线| 7m精品福利视频导航| 国产精品日韩在线一区| 国内外成人免费激情在线视频网站| 91精品国产高清久久久久久| 欧美成人黄色小视频| 久久久久久久久久国产精品| 最近2019年日本中文免费字幕| 91免费国产视频| 国产精品久久久久久久久久三级| 奇米成人av国产一区二区三区| 在线国产精品播放| 日韩av黄色在线观看| 亚洲一区制服诱惑| 午夜精品在线观看| 一道本无吗dⅴd在线播放一区| 影音先锋欧美精品| 国产亚洲精品日韩| www.日韩视频| 欧美最顶级的aⅴ艳星| 国模gogo一区二区大胆私拍| 国产精品激情av在线播放| 91香蕉国产在线观看| 欧美在线视频在线播放完整版免费观看| 久久夜精品香蕉| 中日韩午夜理伦电影免费| 中文字幕欧美精品日韩中文字幕| 国产一区深夜福利| 日韩av在线影院| 日韩中文有码在线视频| 一色桃子一区二区| 97久久伊人激情网| 久久久久久久久久国产| 成人网中文字幕| 精品一区二区三区三区| 亚洲免费伊人电影在线观看av| 亚洲小视频在线观看| 欧美日韩成人在线观看| 国产精品jvid在线观看蜜臀| 久久国产精品久久久| 国产精品亚洲第一区| 91超碰caoporn97人人| 日韩av在线最新| 欧美成人免费在线观看|