導語
java.net.HttpURLConnectin類是URLConnection類的抽象子類。它在處理協議為HTTP的URL時特別有效。具體而言,它通過它可以獲取和設置請求方法,確定是否重定向,獲取響應碼和消息體,以及是否使用代理。由於這個類是一個抽象類,所以不能直接創建它的實例。不過可以通過強轉的方式來獲取 HttpURLConnection對象。
獲取一個HttpURLConnection對象
URL url = new URL("http://www.xdysite.cn/index.php");
HttpURLConnection http = (HttpURLConnection) url.openConnection();
請求方法
HTTP請求中的常用方法包含一下幾個
- GET
- POST
- HEAD
- PUT
- DELETE
HEAD
HEAD方法是最簡單的方法。這個方法和GET方法很類似。不過,它告訴服務器只返回HTTP首部,不用實際發送消息體。這個方法最常見的用途是檢查當前客戶端緩存的文件是否與服務器一致(服務器可能會對文件做修改操作)。下面是個使用HEAD請求方法的簡單程序,它會顯示服務器中一個文件最后一次修改時間。
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://www.xdysite.cn/index.html");
try {
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("HEAD");
System.out.println("該資源最后一次修改時間"+ new Date(http.getLastModified()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
執行結果
服務器資源
http://cgblb.img48.wal8.com/img48/563395_20161212173407/s/148163323406_medium.jpg
這里並不一定非要使用HEAD方法,也可以利用GET來得到同樣的結果。不過使用GET方式的話,服務器會發送該資源。而我們只關心首部中的文件的最后修改時間而已。
DELETE
DELETE方法將刪除Web服務器上位於指定URL的文件。由於這個請求存在明顯的安全風險,所以並非所有的服務器都配置支持這個方法,即使支持該方法通常也需要進行身份認證。典型的請求方式如下:
DELETE /javafaq/2016march.html HTTP/1.1
Host: www.xdysite.cn
Accept: text/html,image/gif,image/jpeg,*;q=0.2
Connection: keep-alive
如果服務器接受這個請求,其響應也與實現有關。有的服務器會刪除文件,有的則會將文件放到回收站中。另外一些則只是將這個文件標記為不可讀。
PUT
如果我們需要將文件放到Web服務器上,則可以采用該方法。這個方法允許客戶端放在網站的抽象層次結構中,而不需要知道網站是如何映射到具體的本地文件系統的。這與FTP正相反,FTP用戶必須知道實際的目錄結構,而不是服務器的虛擬目錄結構。下面顯示如何利用PUT方式將一個文件放在Web服務器上
PUT /blog/wp-app.php/service/testput.html HTTP/1.1
Host: www.xdysite.cn
Content-Type: application/xml;type=entry
Content-Length: 329
If-Match: "ertr2361fgt9733"
<?xml version="1.0">
<entry>
<title>The Power of Pomodoros</title>
<author><name>Elliotte Harold</name></author>
</entry>
與刪除文件一樣,PUT通常也需要進行某種身份認證。而大多數服務器須配置為支持PUT方式
HTTP長連接
HTTP1.1支持長連接,允許通過一個TCP socket發送多個請求和相應。在請求頭和響應頭中需要顯示包含Connection: Keep-Alive元數據。HTTPURLConnection類透明的支持HTTP keep-alive,即默認情況下長連接是打開的。在服務器關閉連接之前,如果再次連接同一個服務器,它會重用socket。
流模式
每個發送給HTTP服務器的請求都有一個HTTP首部。首部中有一個Content-lenght字段,即請求主體中的字節數。不過,寫入首部,需要知道主體的長度,但是在寫首部的時候可能還不知道主體的長度。正常情況下,對於這個兩難的問題,JAVA的解決辦法是:對於從HTTPURLConnection獲取的OutputStream,會將寫入此流的所有內容進行緩存,直到流關閉。此時它就知道主體中有多少個字節了。
這種模式對於表單的短請求很合適。不過,對於非常長的表單或一些SOAP消息,相應時負擔很大。因為要緩存整個數據。JAVA為這個問題提供了兩個解決方案。如果知道數據的大小,則可以將數據大小告訴HTTPURLConnection對象。如果預先不知道數據大小,則可以使用分塊傳輸方式。
public void setFixedLengthStreamingMode(long contentLength)
通過該API可以告訴HttpURLConnection數據的大小。這樣JAVA就會在HTTP首部的Content-Length字段中使用這個數。不過如果最終寫入的數據多於或少於這個字節數,則會拋出一個IOException。
public void setChunkedStreamingMode(int chunkLength)
在使用該API設置好塊的大小后,然后我們可以通過OutputStream發送數據。每當緩存中的數據量累計到設定的值后,java就會把緩存的中的數據輸出。這是數據的發送方式就是塊方式(chunked)。