文章目錄
URLConnection是一個抽象類,它表示指向URL指定資源的活動連接。
打開URLConnection
直接使用URLConnection類的程序遵循以下基本步驟:
- 構造一個URL對象。
- 調用這個URL對象的openConnectio()獲取一個對應該URL的URLConnection對象。
- 配置這個URLConnection對象。
- 讀取首部字段。
- 獲得輸入流並讀取數據。
- 獲得輸出流並寫入數據。
- 關閉連接。
讀取服務器的數據
使用URLConnection對象從一個URL獲取數據的步驟:
- 構造一個URL對象。
- 調用這個URL對象的openConnectio()獲取一個對應該URL的URLConnection對象。
- 調用這個URLConnection的getInputStream()方法,返回一個通用的InputStream。
- 使用通常的流API讀取輸入流。
URL和URLConnection之間的區別:
- URLConnection提供了對HTTP首部的訪問。
- URLConnection可以配置發送給服務器的請求參數。
- URLConnection除了讀取服務器數據以外,還可以向服務器寫入數據。
讀取首部
獲取指定的首部字段
public String getContentType()
:返回內容類型,如text/html、text/plain、image/gif、application/xml和image/jpg,如果沒有返回null;如果內容類型是文本,那麼還可能包含一個字符集部分來標識文檔的字符編碼方式,如Content-type:text/html; charset=UTF-8
。public long getContentLengthLong()
:返回內容中有多少字節,如果沒有返回-1。public String getContentEncoding()
:返回內容編碼方式,最常用的內容編碼方式是x-gzip。字符編碼方式由content-type給出,指出如何將字符編碼爲字節,內容編碼方式指出如何將字節編碼爲其它字節。public long getDate()
:返回文檔的發送時間,按自格林尼治時間過去了多少毫秒給出,可以轉換爲一個java.util.Date。public long getExpiration()
:返回文檔的過期時間。public long getLastModified()
:返回文檔的最後修改時間。
獲取任意首部字段
public String getHeaderField(String name)
:返回指定首部字段的值,首部字段不區分大小寫,並且結果一律返回爲String。public String getHeaderFieldKey(int n)
:返回第n個首部字段的鍵(字段名),實際的第一個首部編號爲1。public String getHeaderField(int n)
:返回第n個首部字段的值。public long getHeaderFieldDate(String name, long default)
:獲取首部字段name的值並轉換爲long,失敗則返回default。public int getHeaderFieldInt(String name, int default)
:獲取首部字段name的值並轉換爲int,失敗則返回default。
緩存
- 一般認爲使用GET通過HTTP訪問的頁面應該緩存,使用HTTPS或POST訪問的頁面不應該緩存。
- HTTP首部可以對緩存做出調整:
- Expires首部指示資源的過期時間。
- Cache-control首部提供了細粒度的緩存策略,可以覆蓋Expires首部。
- Last-modified首部指示資源的最後修改時間。
- Etag首部是資源改變時這個資源的唯一標識符。
- 如果本地緩存中有這個資源的一個表示,而且還沒有到它的過期時間,那麼可以直接使用這個資源;如果已經到了它的過期時間,在完成完整的GET之前,可以檢查服務器的HEAD首部,查看資源是否已經改變。
Java的Web緩存
配置連接
protected URL url
:指定了這個URLConnection連接的URL,可以調用getURL()方法獲取這個字段的值。protected boolean connected
:如果連接已經打開爲true,否則爲false。protected boolean allowUserInteraction
:指示是否允許用戶交互,可以在任何時候讀取,但只能在URLConnection連接前設置。protected boolean doInput
:如果可以用來讀取服務器爲true,否則爲false。protected boolean doOutput
:如果可以用來寫入服務器爲true,否則爲false;爲一個http URL將doOutput設置爲true時,請求方法就由GET改爲POST。protected long ifModifiedSince
:指示了放置在If-Modified-Since首部字段中的日期,如果文檔在這個時間後有所修改,服務器就會發送該文檔。protected boolean useCaches
:指示是否可以使用緩存。
超時
setConnectTimeout(int timeout)/getConnectTimeout()
控制socket等待建立連接的時間;setReadTimeout(int timeout)/getReadTimeout()
控制輸入流等待數據到達的時間。timeout=0
爲永遠不超時。
配置客戶端請求HTTP首部
public void setRequestProperty(String name, String value)
:用指定的名和值爲這個URLConnection的首部設置一個字段。public void addRequestProperty(String name, String value)
:用指定的名和值爲這個URLConnection的首部增加一個字段。public String getRequestProperty(String name)
:查看URLConnection首部的指定字段。-
public Map<String, List<String>> getRequestProperties()
:查看URLConnection首部的所有字段。
向服務器寫入數據
提交表單數據需要以下幾個步驟:
- 確定要發送給服務器程序的名-值對。
- 編寫接受和處理請求的服務器端程序。如果沒有使用定製數據編碼,可以使用普通的HTML表單和Web瀏覽器測試這個程序。
- 在Java程序中創建一個查詢字符串,字符串應當形式如下:name1=value1&name2=value2&name3=value3。在增加到查詢字符串之前,先將各個名和值傳遞到URLEncoder.encode()。
- 打開一個URLConnection,指向將接受數據的程序的URL。
- 調用setDoOutput(true)設置doOutput爲true。
- 將查詢字符串寫入到URLConnection的OutputStream。
- 關閉URLConnection的OutputStream。
- 從URLConnection的InputStream讀取服務器的響應。
URLConnection的安全考慮
public Permission getPermission() throws IOException
:返回一個java.security.Permission對象,指出連接這個URL所需的權限。
猜測MIME媒體類型
public static String guessContentTypeFromName(String name)
:根據對象URL的文件擴展名部分猜測對象的內容類型。public static String guessContentTypeFromStream(InputStream in)
:嘗試查看流中前幾字節來猜測內容類型。
HttpURLConnection
HTTPURLConnection類是URLConnection的抽象子類,唯一的構造函數是保護類型的,不能直接創建實例。如果使用http URL構造一個URL對象並調用其openConnection()方法,返回URLConnection就是HttpURLConnection的一個實例。
URL u = new URL("http://lesswrong.com/");
HttpURLConnection http = (HttpURLConnection) u.openConnection();
請求方法
- 請求行:方法名+資源路徑+HTTP版本。方法包括GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE,可以使用
public void setRequestMethod(String method) throws ProtocolException
來設置。 - HEAD:告訴服務器只返回HTTP首部,不用實際發送文件,常用來檢查文件在最後一次緩存之後是否有修改。
- DELETE:刪除Web服務器上位於指定URL的文件。
- PUT:允許客戶端將文檔放在網站的抽象層次結構中,而不需要知道網站如何映射到實際的本地文件系統。
- OPTIONS:詢問某個特定URL支持哪些選項。
- TRACE:發送HTTP首部,服務器將從客戶端接受這個HTTP首部,查看服務器和客戶端之間的代理服務器做了哪些修改。
斷開與服務器的連接
- HTTP 1.1支持持久連接,允許通過一個TCP socket發送多個請求和響應。
public abstract void disconnect()
:客戶端斷開連接。
處理服務器響應
public int getResponseCode() throws IOException
:返回響應碼public String getResponseMessage() throws IOException
:返回響應消息public InputStream getErrorStream()
:服務器遇到錯誤後返回的消息,應該在catch模塊中調用。public static boolean getFollowRedirects()
:如果跟隨重定向返回true。public static void setFollowRedirects()
:設置是否跟隨重定向。
代理
public abstract boolean usingProxy()
:指出某個HttpURLConnection是否通過代理服務器。
流模式
- 對於從HttpURLConnection獲取的OutputStream,將寫入此OutputStream的所有內容緩存,直到流關閉,此時就會知道主體中有多少字節,有足夠的信息寫入Content-length首部。
public void setChunkedStreamingMode(int chunkLength)
:在連接URL之前將分塊大小傳入該方法,可以啓用分塊傳輸編碼方式。public void setFixedLengthStreamingMode(long contentLength)
:將傳輸數據的具體大小傳入該方,寫入首部的Content-length字段。