Servlet&JSP的那些事兒(三)

來源:互聯網
上載者:User

我們在Servlet解析(二)中討論了Servlet
UML 類圖中的Servlet介面,本篇我們將繼續討論ServletRequest、ServletResponse、ServletConfig。除此之外還有Servlet異常、Servlet上下文。

ServletRequest和ServletResponse

ServletRequest和ServletResponse介面都在javax.servlet包中定義。ServletRequest介面中的常用方法如下:

public java.lang.Object getAttribute(java.lang.String name)//返回以name為名字的屬性的值。如果該屬性不存在,這個方法將返回null。public java.util.Enumeration getAttributeNames()//返回請求中所有可用的屬性的名字。如果在請求中沒有屬性,這個方法將返回一個空的枚舉集合。public void removeAttribute(java.lang.String name)//移除請求中名字為name的屬性。public void setAttribute(java.lang.String name, java.lang.Object o)//在請求中儲存名字為name的屬性。如果第二個參數o為null,那麼相當於調用removeAttribute(name)。public java.lang.String getCharacterEncoding()//返回請求本文使用的字元編碼的名字。如果請求沒有指定字元編碼,這個方法將返回null。public int getContentLength()//以位元組為單位,返回請求本文的長度。如果長度不可知,這個方法將返回-1。public java.lang.String getContentType()//返回請求本文的MIME類型。如果類型不可知,這個方法將返回null。public ServletInputStream getInputStream()//返回一個輸入資料流,使用該輸入資料流以二進位方式讀取請求本文的內容。javax.servlet.ServletInputStream是一個抽象類別,繼承自java.io.InputStream。public java.lang.String getLocalAddr()//返回接收到請求的網路介面的IP地址,這個方法是在Servlet 2.4規範中新增的方法。public java.lang.String getLocalName()//返回接收到請求的IP介面的主機名稱,這個方法是在Servlet 2.4規範中新增的方法。public int getLocalPort()//返回接收到請求的網路介面的IP連接埠號碼,這個方法是在Servlet 2.4規範中新增的方法。public java.lang.String getParameter(java.lang.String name)//返回請求中name參數的值。如果name參數有多個值,那麼這個方法將傳回值列表中的第一個值。如果在請求中沒有找到這個參數,這個方法將返回null。public java.util.Enumeration getParameterNames()//返回請求中包含的所有的參數的名字。如果請求中沒有參數,這個方法將返回一個空的枚舉集合。public java.lang.String[] getParameterValues(java.lang.String name)//返回請求中name參數所有的值。如果這個參數在請求中並不存在,這個方法將返回null。public java.lang.String getProtocol()  //返回請求使用的協議的名字和版本,例如:HTTP/1.1。public java.io.BufferedReader getReader() throws java.io.IOException//返回BufferedReader對象,以字元資料方式讀取請求本文。public java.lang.String getRemoteAddr()//返回傳送請求的用戶端或者最後一個Proxy 伺服器的IP地址。public java.lang.String getRemoteHost()//返回傳送請求的用戶端或者最後一個Proxy 伺服器的完整限定名。public int getRemotePort()//返回傳送請求的用戶端或者最後一個Proxy 伺服器的IP源連接埠public RequestDispatcher getRequestDispatcher(java.lang.String path)//返回RequestDispatcher對象,作為path所定位的資源的封裝。public java.lang.String getServerName()//返回請求發送到的伺服器的主機名稱。public int getServerPort()  //返回請求發送到的伺服器的連接埠號碼。public void setCharacterEncoding (java.lang.String env)throws java.io.Unsupported EncodingException//覆蓋在請求本文中所使用的字元編碼的名字。

ServletResponse介面中的常用方法如下:

public void flushBuffer() throws java.io.IOException//強制把任何在緩衝中的內容發送到用戶端。public int getBufferSize()//返回實際用於響應的緩衝的大小。如果沒有使用緩衝,這個方法將返回0。public java.lang.String getCharacterEncoding()  //返回在響應中發送的本文所使用的字元編碼(MIME字元集)。public java.lang.String getContentType()//返回在響應中發送的本文所使用的MIME類型。public ServletOutputStream getOutputStream() throws java.io.IOException//返回ServletOutputStream對象,用於在響應中寫入位元據。javax.servlet. ServletOutputStream是一個抽象類別,繼承自java.io.OutputStream。public java.io.PrintWriter getWriter() throws java.io.IOException//返回PrintWriter對象,用於發送字元文本到用戶端。PrintWriter對象使用getCharacterEncoding()方法返回的字元編碼。如果沒有指定響應的字元編碼方式,預設將使用ISO-8859-1。public boolean isCommitted()//返回一個布爾值,指示是否已經提交了響應。public void reset()//清除在緩衝中的任何資料,包括狀態碼和訊息前序。如果響應已經被提交,這個方法將拋出IllegalStateException異常。public void resetBuffer()//清除在緩衝中的響應內容,保留狀態碼和訊息前序。如果響應已經被提交,這個方法將拋出IllegalStateException異常。public void setBufferSize(int size)//設定響應本文的緩衝大小。Servlet容器將使用一個緩衝,其大小至少是請求的尺寸大小。這個方法必須在響應本文被寫入之前調用,如果內容已經被寫入或者響應對象已經被提交,這個方法將拋出IllegalStateException異常。public void setCharacterEncoding(java.lang.String charset)//設定發送到用戶端的響應的字元編碼,例如,UTF-8。public void setContentLength(int len)//對於HTTP Servlet,在響應中,設定內容本文的長度,這個方法設定HTTP Content-Length實體前序。public void setContentType(java.lang.String type)//設定要發送到用戶端的響應的內容類型,此時響應應該還沒有提交。給出的內容類型可以包括字元編碼說明,例如:text/html;charset=UTF-8。如果這個方法在getWriter()方法被調用之前調用,那麼響應的字元編碼將僅從給出的內容類型中設定。這個方法如果在getWriter()方法被調用之後或者在響應被提交之後調用,將不會設定響應的字元編碼。在使用HTTP協議的情況中,這個方法設定Content-Type實體前序。

上面所列的方法,不需要全部記下來,只需要大致瞭解即可。關鍵是要理解請求和響應對象能夠提供哪些方法,只要理解了互動的過程及請求對象和響應對象所起的作用,當我們需要用到某個方法時,完全可以在API文檔中進行尋找。

ServletConfig

在javax.servlet包中,定義了ServletConfig介面。Servlet容器使用ServletConfig對象在Servlet初始化期間向它傳遞配置資訊,一個Servlet只有一個ServletConfig對象。在這個介面中,定義了下面四個方法:

public java.lang.String getInitParameter(java.lang.String name)//返回名字為name的初始化參數的值,初始化參數在web.xml設定檔中進行配置。如果參數不存在,這個方法將返回null。public java.util.Enumeration getInitParameterNames()//返回Servlet所有初始化參數的名字的枚舉集合。如果Servlet沒有初始化參數,這個方法將返回一個空的枚舉集合。public ServletContext getServletContext()//返回Servlet內容物件的引用,關於ServletContext的使用。public java.lang.String getServletName()//返回Servlet執行個體的名字。這個名字是在Web應用程式的部署描述符中指定的。如果是一個沒有註冊的Servlet執行個體,這個方法返回的將是Servlet的類名。

Servlet異常

在javax.servlet包中定義了兩個異常類,ServletException和UnavailableException。

1)ServletException類

ServletException類定義了一個通用的異常,可以被init()、service()和doXXX()方法拋出,這個類提供了下面4個構造方法和1個執行個體方法:

public ServletException()//該方法構造一個新的Servlet異常。public ServletException(java.lang.String message)//該方法用指定的的訊息構造一個新的Servlet異常。這個訊息可以被寫入伺服器的日誌中,或者顯示給使用者。public ServletException(java.lang.String message, java.lang.Throwable rootCause)//在Servlet執行時,如果有一個異常阻礙了Servlet的正常操作,那麼這個異常就是根原因(root cause)異常。如果需要在一個Servlet異常中包含根原因的異常,可以調用這個構造方法,同時包含一個描述訊息。例如:可以在ServletException異常中嵌入一個java.sql.SQLException異常。public ServletException(java.lang.Throwable rootCause)//該方法同上,只是沒有指定描述訊息的參數。public java.lang.Throwable getRootCause()//該方法返回引起這個Servlet異常的異常,也就是返回根原因的異常。

2)UnavailableException類

UnavailableException類是ServletException類的子類,該異常被Servlet拋出,用於向Servlet容器指示這個Servlet永久地或者暫時地不可用。這個類提供了下面2個構造方法和2個執行個體方法:

public UnavailableException(java.lang.String msg)//該方法用一個給定的訊息構造一個新的異常,指示Servlet永久不可用。public UnavailableException(java.lang.String msg, int seconds)//該方法用一個給定的訊息構造一個新的異常,指示Servlet暫時不可用。其中的參數seconds指明在這個以秒為單位的時間內,Servlet不可用。如果Servlet不能估計出多長時間後它將恢複功能,可以傳遞一個負數或零給seconds參數。public int getUnavailableSeconds()//該方法返回Servlet預期的暫時停用秒數。如果返回一個負數,表明Servlet永久不可用或者不能估計出Servlet多長時間不可用。public boolean isPermanent()//法回一個布爾值,用於指示Servlet是否是永久不可用。返回true,表明Servlet永久不可用;返回false,表明Servlet可用或者暫時不可用。

ServletContext介面

一個ServletContext對象表示了一個Web應用程式的上下文。Servlet容器在Servlet初始化期間,向其傳遞ServletConfig對象,可以通過ServletConfig對象的getServletContext()方法來得到ServletContext對象。也可以通過GenericServlet類的getServletContext()方法得到ServletContext對象,不過GenericServlet類的getServletContext()也是調用ServletConfig對象的getServletContext()方法來得到這個對象的。

ServletContext介面定義了下面的這些方法,Servlet容器提供了這個介面的實現。

public java.lang.Object getAttribute(java.lang.String name)public java.util.Enumeration getAttributeNames()public void removeAttribute(java.lang.String name)public void setAttribute(java.lang.String name, java.lang.Object object)

上面4個方法用於讀取、移除和設定共用屬性,任何一個Servlet都可以設定某個屬性,而同一個Web應用程式的另一個Servlet可以讀取這個屬性,不管這些Servlet是否為同一個客戶進行服務。

public ServletContext getContext(java.lang.String uripath)

該方法返回伺服器上與指定的URL相對應的ServletContext對象。給出的uripath參數必須以斜杠(/)開始,被解釋為相對於伺服器文檔根的路徑。出於安全方面的考慮,如果調用該方法訪問一個受限制的ServletContext對象,那麼該方法將返回null。

public String getContextPath()

該方法用於返回Web應用程式的上下文路徑。上下文路徑總是以斜杠(/)開頭,但結束沒有斜杠(/)。在預設(根)上下文中,這個方法返回Null 字元串""。

public java.lang.String getInitParameter(java.lang.String name)public java.util.Enumeration getInitParameterNames()

可以為Servlet上下文定義初始化參數,這些參數被整個Web應用程式所使用。可以在部署描述符(web.xml)中使用<context-param>元素來定義內容相關的初始化參數,上面兩個方法用於訪問這些參數。

public int getMajorVersion()public int getMinorVersion()

上面兩個方法用於返回Servlet容器支援的Java Servlet API的主要版本和次版本號碼。例如,對於遵從Servlet 2.4版本的容器,getMajorVersion()方法返回2,getMinorVersion()方法返回4。

public java.lang.String getMimeType(java.lang.String file)

該方法返回指定檔案的MIME類型,如果類型是未知的,這個方法將返回null。MIME類型的檢測是根據Servlet容器的配置,也可以在Web應用程式的部署描述符中指定。

public RequestDispatcher getRequestDispatcher(java.lang.String path)

該方法返回一個RequestDispatcher對象,作為指定路徑上的資源的封裝。可以使用RequestDispatcher對象將一個請求轉寄(forward)給其他資源進行處理,或者在響應中包含(include)資源。要注意的是,傳入的參數path必須以斜杠(/)開始,被解釋為相對於當前上下文根(context root)的路徑。

public RequestDispatcher getNamedDispatcher(java.lang.String name)

該方法與getRequestDispatcher()方法類似。不同之處在於,該方法接受一個在部署描述符中以<servlet-name>元素給出的Servlet(或JSP頁面)的名字作為參數。

public java.lang.String getRealPath(java.lang.String path)

在一個Web應用程式中,資源用相對於上下文路徑的路徑來引用,這個方法可以返回資源在伺服器檔案系統上的真實路徑(檔案的絕對路徑)。返回的真實路徑的格式應該適合於運行這個Servlet容器的電腦和作業系統(包括正確的路徑分隔字元)。如果Servlet容器不能夠將虛擬路徑轉換為真實的路徑,這個方法將會返回null。

public java.net.URL getResource(java.lang.String path) throws java.net.Malformed URLException

該方法返回被映射到指定路徑上的資源的URL。傳入的參數path必須以斜杠(/)開始,被解釋為相對於當前上下文根(context root)的路徑。這個方法允許Servlet容器從任何來源為Servlet產生一個可用的資源。資源可以是在本地或遠程檔案系統上,在資料庫中,或者在WAR檔案中。如果沒有資源地圖到指定的路徑上,該方法將返回null。

public java.io.InputStream getResourceAsStream(java.lang.String path)

該方法與getResource()方法類似,不同之處在於,該方法返回資源的輸入資料流對象。另外,使用getResourceAsStream()方法,元資訊(如內容長度和內容類型)將丟失,而使用getResource()方法,元資訊是可用的。

public java.util.Set getResourcePaths(java.lang.String path)

該方法返回資源的路徑列表,參數path必須以斜杠(/)開始,指定用於匹配資源的部分路徑。例如,一個Web應用程式套件組合含了下列資源:

/welcome.html
/catalog/index.html
/catalog/products.html
/catalog/offers/books.html
/catalog/offers/music.html
/customer/login.jsp
/WEB-INF/web.xml
/WEB-INF/classes/com.acme.OrderServlet.class
如果調用getResourcePaths("/"),將返回[/welcome.html, /catalog/, /customer/, /WEB-INF/]。如果調用getResourcePaths("/catalog/"),將返回[/catalog/index.html,/catalog/products.html, /catalog/offers/]。

public java.lang.String getServerInfo()

該方法返回運行Servlet的容器的名稱和版本。

public java.lang.String getServletContextName()

該方法返回在部署描述符中使用<display-name>元素指定的對應於當前ServletContext的Web應用程式的名稱。

public void log(java.lang.String msg)public void log(java.lang.String message, java.lang.Throwable throwable)

ServletContext介面提供了上面兩個記錄日誌的方法,第一個方法用於記錄一般的日誌,第二個方法用於記錄指定異常的棧跟蹤資訊。

一個簡單樣本:統計訪問次數

很多網站都有統計訪問次數的功能,我們可以使用ServletContext對象來儲存訪問的次數。我們知道一個Web應用程式只有一個ServletContext對象,而且該對象可以被Web應用程式中的所有Servlet所訪問,因此使用ServletContext對象來儲存一些需要在Web應用程式中共用的資訊是再合適不過了。

要在ServletContext對象中儲存共用資訊,可以調用該對象的setAttribute()方法,要擷取共用資訊,可以調用該對象的getAttribute()方法。針對本例,我們可以調用setAttribute()方法將訪問計數儲存到內容物件中,新增一次訪問時,調用getAttribute()方法從內容物件中取出訪問計數加1,然後再調用setAttribute()方法儲存回內容物件中。

我們接著繼續以MyDemo為web工程,在com.shan.web包下建立CounterServlet類,即在MyDemo\src\com\shan\web目錄下建立CounterServlet.java,代碼如下所示。

package com.shan.web;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;/** ** A Count Servlet ** @author shan **/public class CounterServlet extends HttpServlet{public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException {ServletContext context = getServletContext();Integer count = null;synchronized(context) {count = (Integer) context.getAttribute("counter");if (null == count) {count = new Integer(1);} else {count = new Integer(count.intValue() + 1);}context.setAttribute("counter", count);}response.setContentType("text/html;charset=gb2312");PrintWriter out = response.getWriter();out.println("<html><head>");out.println("<title>頁面訪問統計</title>");out.println("</head><body>");out.println("該頁面已被訪問了" + "<b>" + count + "</b>" + "次");out.println("</body></html>");out.close();}}

程式調用getServletContext()方法(從GenericServlet類間接繼承而來)得到Web應用程式的內容物件。為了避免安全執行緒的問題,使用了synchronized關鍵字對context對象進行同步。通過調用內容物件的getAttribute()方法擷取counter屬性的值。並判斷count是否為null,如果為null,則將它的初始值設為1。當這個Servlet第一次被訪問的時候,在內容物件中還沒有儲存counter屬性,所以擷取該屬性的值將返回null。如果count不為null,則將count加1。通過將count作為counter屬性的值儲存到ServletContext對象中。

編寫完上述代碼之後,需要對代碼進行編譯,執行如下語句:

javac -classpath D:\apache-tomcat-7.0.33\lib\servlet-api.jar -d classes src\com\shan\web\CounterServlet.java

將編譯後的classes檔案夾複製到D:\apache-tomcat-7.0.33\webapps\MyDemo檔案夾中。接下來還需要修改web.xml檔案,修改後的檔案如下:

<?xml version='1.0' encoding='utf-8'?><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">    <description>      My Demo.    </description><servlet><servlet-name>selectServlet</servlet-name><servlet-class>com.shan.web.MyDemoServlet</servlet-class></servlet><servlet><servlet-name>countServlet</servlet-name><servlet-class>com.shan.web.CounterServlet</servlet-class></servlet><servlet-mapping><servlet-name>selectServlet</servlet-name><url-pattern>/SelectColor.do</url-pattern></servlet-mapping><servlet-mapping><servlet-name>countServlet</servlet-name><url-pattern>/count.do</url-pattern></servlet-mapping></web-app>

將web.xml檔案複製到D:\apache-tomcat-7.0.33\webapps\MyDemo\WEB-INF檔案夾下。啟動Tomcat,在瀏覽器中輸入http:localhost:8080/MyDemo/count.do即可看到結果。

交替重新整理兩個瀏覽器中的頁面,可以看到訪問次數也在交替增長,說明利用ServletContext儲存屬性,可以在多個用戶端之間共用屬性。但要注意,不同的Web應用程式具有不同的Servlet上下文,所以在不同的Web應用程式之間不能利用ServletContext來共用屬性。另外,訪問次數在重啟Tomcat伺服器後,將重新從1開始,為了永久儲存訪問次數,可以將這個值儲存到檔案或資料庫中。

轉載請註明出處:http://blog.csdn.net/iAm333

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.