Java網路02 Servlet開胃酒HTTP協議

來源:互聯網
上載者:User

作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝!

 

在Tomcat初次嘗試中,我們搭建了用於測試Servlet和JSP的基本環境。我們現在要轉向網路應用的具體開發。

 

廚師

Web伺服器的基本工作方式是請求-處理-回複。請求和回複是在網路上,以HTTP協議為基礎的通訊(參考HTTP協議)。請求是客戶點菜,回複像是服務員上菜,而處理則是在後廚中,廚師根據請求的菜單,準備菜品的過程。

廚師通常是伺服器上的一個應用程式。這個應用程式可以提取請求中的資訊,並根據這些資訊準備回複。這樣的應用程式可以是許多中語言寫成的,比如C, C++, Perl, Ruby, Python, Ruby, PHP等等。由於不同語言的設計理念和編譯器特徵的不同,這些語言寫成的應用程式也有不同的特點(各種各樣的廚師)。比如C和C++語言會有比較高的運行效率,PHP的Web應用廣泛,Ruby和Python開發方便等等。

(在語言之爭中,Web伺服器的“後廚”是一塊兵家必爭之地)

Servlet是Java語言提供的的“廚師”。在Java中,“一切皆對象”。Servlet是一類特殊的Java對象。Java語言利用Servlet對象,來實現對HTTP請求的處理。

 

範例

下面是一個簡單的Servlet例子,源檔案為TestPage.java:

package foo;import javax.servlet.*;import javax.servlet.http.*;import java.io.*;public class TestPage extends HttpServlet {    public void doGet(HttpServletRequest request,                     HttpServletResponse response)                throws IOException, ServletException    {        PrintWriter out = response.getWriter();        out.println("<html><body>" +           "<p>Hello World!</p>" + "</body></html>");    }}

這個Servlet的功能是回複字串"<html><body><p>Hello World!</p></body></html>"。這一段字串實際上是一個HTML文本。它將作為HTTP回複的主體部分,發回給用戶端。

這裡定義了一個TestPage類,該類繼承HttpServlet抽象類別(參考HttpServlet)。我們覆蓋了doGet()方法。doGet()方法處理GET方法的HTTP請求。如果HTTP請求的方法為POST,則應該覆蓋doPost()方法。每個Servlet都應該覆蓋doGet()和doPost()之一。doGet()和doPost()方法接收兩個參數request和response,分別為HttpServletRequest類型和HttpServletResponse類型。這兩個參數分別代表該次HTTP通訊的請求和回複。

HttpServletRequest和HttpServletResponse為兩個介面。在方法的內部,我們可以操作request和response對象。比如,通過response的getWriter方法,來獲得Writer,從而寫入HTML文本。這些寫入的文本將作為HTTP回複的主體傳遞迴用戶端。再比如,我們可以使用request的getMethod()方法來獲知HTTP請求的方法。可以參考下面的官方文檔:

HttpServletRequest的更多方法

HttpServletResponse的更多方法

 

此外,PrintWriter類來自java.io包。參考Java IO

 

doGet()是真正的工作室。我們通過定義該方法(或者doPost())方法,來讓廚師做特定的事情。Servlet編寫的關鍵在於寫出一個符合需求的doGet()方法或者doPost()方法。

 

doGet()與doPost()

正如第一行package語句所說明的(參考Java包),TestPage類被放入到foo包中。我們還import了其他的Java包。Servlet是基於Java的,所以它可以藉助Java語言所提供的豐富的工具。

 

編譯

使用下面命令編譯TestPage.java

$javac -classpath /path-to-tomcat/lib/servlet-api.jar:classes:. TestPage.java

上面的path-to-tomcat是Tomcat的安裝路徑。我們需要包括servlet-api.jar,原因是,javax.servlet包屬於J2EE,它並不屬於JSE。

 

將編譯產生的TestPage.class檔案放入到下面的檔案夾中。(如果檔案夾不存在,需要自行建立):

/path-to-tomcat/webapps/test/WEB-INF/classes/foo

(在TesPage.java中,利用package語句,說明該類在foo包中。這裡的路徑符合之前的package定義。)

 

修改或者建立/path-to-tomcat/webapps/test/WEB-INFO/web.xml

<?xml version="1.0" encoding="ISO-8859-1"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more  contributor license agreements.  See the NOTICE file distributed with  this work for additional information regarding copyright ownership.  The ASF licenses this file to You under the Apache License, Version 2.0  (the "License"); you may not use this file except in compliance with  the License.  You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and  limitations under the License.--><web-app xmlns="http://java.sun.com/xml/ns/javaee"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  version="3.0"  metadata-complete="true">  <servlet>    <servlet-name>Test</servlet-name>    <servlet-class>foo.TestPage</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>Test</servlet-name>    <url-pattern>/MyServlet</url-pattern>  </servlet-mapping> </web-app>

這樣的一個xml檔案被稱作部署描述(DD, Deployment Descriptor)。DD告訴Container如何運行Servlet和JSP。

上面的<servlet>標籤是將該Servlet(foo.TestPage.class)命名為Test。

在<servlet-mapping>標籤中,我們將Test這個Servlet對應於URL: /MyServlet。這說明,當有請求訪問該URL時,則將請求傳遞給Test這個Servlet處理。

上面修改的主要目的,是說明Servlet與URL的對應關係。

 

隨後,可以訪問localhost:8080/test/MyServlet,來查看訪問頁面。

 

過程

看一下Servlet完成一次請求處理的過程:

從用戶端(Guest)向伺服器發送HTTP請求,該HTTP請求傳遞給Servlet Container。該Container負責:

  • 分析HTTP請求的資訊,並建立request對象,將HTTP請求中的資訊放入request對象
  • 建立response對象
  • 根據web.xml,尋找URL對應的Servlet對象。如果Servlet對象不存在,則建立相應Servlet對象。
  • 建立新的線程,用於處理本次請求。線程擁有指向request和response對象的引用。

 

線程將調用Servlet的doGet()或者doPost()方法。線程運行結束後,response對象將傳回給Container。Container根據response對象中的資訊,產生一個符合HTTP協議的回複,傳回給用戶端。

注意,即使是建立的Servlet對象,它也不會隨著線程的結束而結束。Servlet將繼續存在。下次相同的URL訪問將不必建立Servlet。

 

總結

上面製作了一個簡單的Servlet,主要用於說明製作Servlet的過程。Servlet的許多強大功能還有待以後展開。

每個Servlet就像是後廚的一個廚師。我們可以用不同的URL對應來選擇不同的廚師。一個複雜的網站往往需要許多個不同功能的Servlet。

 

歡迎繼續閱讀“Java快速教程”系列文章

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.