- Java核心技術·卷Ⅱ:高級特性(原書第10版)
- (美)凱S.霍斯特曼
- 2549字
- 2020-10-30 18:10:58
4.4.2 使用URLConnection獲取信息
如果想從某個Web資源獲取更多信息,那么應該使用URLConnection類,通過它能夠得到比基本的URL類更多的控制功能。
當操作一個URLConnection對象時,必須像下面這樣非常小心地安排操作步驟:
1)調用URL類中的openConnection方法獲得URLConnection對象:

2)使用以下方法來設置任意的請求屬性:

我們將在本節的稍后部分以及API說明中討論這些方法。
3)調用connect方法連接遠程資源:

除了與服務器建立套接字連接外,該方法還可用于向服務器查詢頭信息(header information)。
4)與服務器建立連接后,你可以查詢頭信息。getHeaderFieldKey和getHeaderField這兩個方法枚舉了消息頭的所有字段。getHeaderFields方法返回一個包含了消息頭中所有字段的標準Map對象。為了方便使用,以下方法可以查詢各標準字段:

5)最后,訪問資源數據。使用getInputStream方法獲取一個輸入流用以讀取信息(這個輸入流與URL類中的openStream方法所返回的流相同)。另一個方法getContent在實際操作中并不是很有用。由標準內容類型(比如text/plain和image/gif)所返回的對象需要使用com.sun層次結構中的類來進行處理。也可以注冊自己的內容處理器,但是在本書中我們不討論這項技術。
警告:一些程序員在使用URLConnection類的過程中形成了錯誤的觀念,他們認為URLConnection類中的getInputStream和getOutputStream方法與Socket類中的這些方法相似,但是這種想法并不十分正確。URLConnection類具有很多表象之下的神奇功能,尤其在處理請求和響應消息頭時。正因為如此,嚴格遵循建立連接的每個步驟顯得非常重要。
下面將詳細介紹一下URLConnection類中的一些方法。有幾個方法可以在與服務器建立連接之前設置連接屬性,其中最重要的是setDoInput和setDoOutput。在默認情況下,建立的連接只產生從服務器讀取信息的輸入流,并不產生任何執行寫操作的輸出流。如果想獲得輸出流(例如,用于向一個Web服務器提交數據),那么你需要調用:

接下來,也許想設置某些請求頭(request header)。請求頭是與請求命令一起被發送到服務器的。例如:

setIfModifiedSince方法用于告訴連接你只對自某個特定日期以來被修改過的數據感興趣;setUseCaches和setAllowUserInteraction這兩個方法只作用于Applet;setUseCaches方法用于命令瀏覽器首先檢查它的緩存;setAllowUserInteraction方法則用于在訪問有密碼保護的資源時彈出對話框,以便查詢用戶名和口令(見圖4-7)。
最后我們再介紹一個總覽全局的方法:setRequestProperty,它可以用來設置對特定協議起作用的任何“名-值(name/value)對”。關于HTTP請求頭的格式,請參見RFC 2616,其中的某些參數沒有很好地建檔,它們通常在程序員之間口頭傳授。例如,如果你想訪問一個有密碼保護的Web頁,那么就必須按如下步驟操作:
1)將用戶名、冒號和密碼以字符串形式連接在一起。

2)計算上一步驟所得字符串的Base64編碼。(Base64編碼用于將字節序列編碼成可打印的ASCII字符序列。)

3)用"Authorization"這個名字和"Basic"+encoding的值調用setRequestProperty方法。

提示:我們上面介紹的是如何訪問一個有密碼保護的Web頁。如果想要通過FTP訪問一個有密碼保護的文件時,則需要采用一種完全不同的方法:構建如下格式的URL:


圖4-7 網絡密碼對話框
一旦調用了connect方法,就可以查詢響應頭信息了。首先,我們將介紹如何枚舉所有響應頭的字段。似乎是為了展示自己的個性,該類的實現者引入了另一種迭代協議。調用如下方法:

可以獲得響應頭的第n個鍵,其中n從1開始!如果n為0或大于消息頭的字段總數,該方法將返回null值。沒有哪種方法可以返回字段的數量,你必須反復調用getHeaderFieldKey方法直到返回null為止。同樣地,調用以下方法:

可以得到第n個值。
getHeaderFields方法可以返回一個封裝了響應頭字段的Map對象。

下面是一組來自典型的HTTP請求的響應頭字段。

為了簡便起見,Java提供了6個方法用以訪問最常用的消息頭類型的值,并在需要的時候將它們轉換成數字類型,這些方法的詳細信息請參見表4-1。返回類型為long的方法返回的是從格林尼治時間1970年1月1日開始計算的秒數。
表4-1 用于訪問響應頭值的簡便方法

通過程序清單4-6的程序,可以對URL連接做一些試驗。程序運行起來后,請在命令行中輸入一個URL以及用戶名和密碼(可選),例如:

該程序將輸出以下內容:
·消息頭中的所有鍵和值。
·表4-1中6個簡便方法的返回值。
·被請求資源的前10行信息。
程序清單4-6 urlConnection/URLConnectionTest.java



java.net.URL 1.0
·InputStream openStream()
打開一個用于讀取資源數據的輸入流。
·URLConnection openConnection();
返回一個URLConnection對象,該對象負責管理與資源之間的連接。
java.net.URLConnection 1.0
·void setDoInput(boolean doInput)
·boolean getDoInput()
如果doInput為true,那么用戶可以接收來自該URLConnection的輸入。
·void setDoOutput(boolean doOutput)
·boolean getDoOutput()
如果doOutput為true,那么用戶可以將輸出發送到該URLConnection。
·void setIfModifiedSince(long time)
·long getIfModifiedSince()
屬性ifModifiedSince用于配置該URLConnection對象,使它只獲取那些自從某個給定時間以來被修改過的數據。調用方法時需要傳入的time參數指的是從格林尼治時間1970年1月1日午夜開始計算的秒數。
·void setUseCaches(boolean useCaches)
·boolean getUseCaches()
如果useCaches為true,那么數據可以從本地緩存中得到。請注意,URLConnection本身并不維護這樣一個緩存,緩存必須由瀏覽器之類的外部程序提供。
·void setAllowUserInteraction(boolean allowUserInteraction)
·boolean getAllowUserInteraction()
如果allowUserInteraction為true,那么可以查詢用戶的口令。請注意,URLConnection本身并不提供這種查詢功能。查詢必須由瀏覽器或瀏覽器插件之類的外部程序實現。
·void setConnectTimeout(int timeout)5.0
·int getConnectTimeout()5.0
設置或得到連接超時時限(單位:毫秒)。如果在連接建立之前就已經達到了超時的時限,那么相關聯的輸入流的connect方法就會拋出一個SocketTimeoutException異常。
·void setReadTimeout(int timeout)5.0
·int getReadTimeout()5.0
設置讀取數據的超時時限(單位:毫秒)。如果在一個讀操作成功之前就已經達到了超時的時限,那么read方法就會拋出一個SocketTimeoutException異常。
·void setRequestProperty(String key,String value)
設置請求頭的一個字段。
·Map<String,List<String>>getRequestProperties()1.4
返回請求頭屬性的一個映射表。相同的鍵對應的所有值被放置在同一個列表中。
·void connect()
連接遠程資源并獲取響應頭信息。
·Map<String,List<String>>getHeaderFields()1.4
返回響應的一個映射表。相同的鍵對應的所有值被放置在同一個列表中。
·String getHeaderFieldKey(int n)
得到響應頭第n個字段的鍵。如果n小于等于0或大于響應頭字段的總數,則該方法返回null值。
·String getHeaderField(int n)
得到響應頭第n個字段的值。如果n小于等于0或大于響應頭字段的總數,則該方法返回null值。
·int getContentLength()
如果內容長度可獲得,則返回該長度值,否則返回-1。
·String getContentType()
獲取內容的類型,比如text/plain或image/gif。
·String getContentEncoding()
獲取內容的編碼機制,比如gzip。這個值不太常用,因為默認的identity編碼機制并不是用Content-Encoding頭來設定的。
·long getDate()
·long getExpiration()
·long getLastModified()
獲取創建日期、過期日以及最后一次被修改的日期。這些日期指的是從格林尼治時間1970年1月1日午夜開始計算的秒數。
·InputStream getInputStream()
·OutputStream getOutputStream()
返回從資源讀取信息或向資源寫入信息的流。
·Object getContent()
選擇適當的內容處理器,以便讀取資源數據并將它轉換成對象。該方法對于讀取諸如text/plain或image/gif之類的標準內容類型并沒有什么用處,除非你安裝了自己的內容處理器。
- CockroachDB權威指南
- Mastering Selenium WebDriver
- Learning C++ Functional Programming
- Java從入門到精通(第5版)
- Mastering OpenCV 4
- Building Mobile Applications Using Kendo UI Mobile and ASP.NET Web API
- 零基礎學Python數據分析(升級版)
- Web Development with MongoDB and Node(Third Edition)
- HTML5 APP開發從入門到精通(微課精編版)
- Everyday Data Structures
- SAS編程演義
- JavaScript Unit Testing
- Zend Framework 2 Cookbook
- HTML5程序開發范例寶典
- 微服務設計