1. 程式人生 > >URLConnection概述

URLConnection概述

URLConnection是一個抽象類,表示指向URL指定資源的活動連線。

URLConnection類本身依賴於Socket類實現網路連線。一般認為,URLConnection類提供了比Socket類更易於使用、更高階的網路連線抽象。但實際上,大多數程式設計師都會忽略它。因為URLConnection太貼近HTTP協議。它假定傳輸的內容前面都有MIME首部或類似的東西。但大多數協議(如FTP和SMTP)並不使用MIME首部。

在Android開發中網路請求是最常用的操作之一, Android SDK中對HTTP(超文字傳輸協議)也提供了很好的支援,這裡包括兩種介面:
1、標準Java介面(java.NET) —-HttpURLConnection,可以實現簡單的基於URL請求、響應功能;
2、Apache介面(org.appache.http)—-HttpClient,使用起來更方面更強大。

但在android API23的SDK中Google將HttpClient移除了。Google建議使用httpURLconnection進行網路訪問操作。

所以下面來介紹一下URLConnection中的常用API

URLConnection讀取首部

 @Test
    public void test(){
        try {
            //構造一個到指定 URL 的 URL 連線
            URL url = new URL("http://www.baidu.com");
            URLConnection uc = url.openConnection();
            //返回 Content-type 頭欄位的值。即資料的MIME內容型別。若型別不可用,則返回null。
String contentType = uc.getContentType(); //返回 Content-length 頭欄位的值。該方法獲取內容的位元組數。許多伺服器只有在傳輸二進位制檔案才傳送Content-length首部,在傳輸文字檔案時並不傳送。若沒有該首部,則返回-1。 int contentLength = uc.getContentLength(); //返回 Content-encoding 頭欄位的值。獲取內容的編碼方式。若內容無編碼,則該方法返回null。 String contentEncoding = uc.getContentEncoding(); //返回 date 頭欄位的值。獲取請求的傳送時間。即自1900年1月1日子夜後過去的毫秒數。
long date = uc.getDate(); //返回 expires 頭欄位的值。獲取Expires的值。若無該欄位,則返回0。0即表示不過期,永遠快取。 long expiration = uc.getExpiration(); //返回 last-modified 頭欄位的值。該值是自1900年1月1日子夜後過去的毫秒數。若無該欄位,則返回0。 long lastModified = uc.getLastModified(); System.out.println(contentType); System.out.println(contentLength); System.out.println(contentEncoding); System.out.println(date); System.out.println(expiration); System.out.println(lastModified); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }

這裡寫圖片描述

URLConnection獲取任意首部欄位

  @Test
    public void test2(){
        try {
            //構造一個到指定 URL 的 URL 連線
            URL url = new URL("http://www.baidu.com");
            URLConnection uc = url.openConnection();
            //返回指定的頭欄位的值。
            String contentType = uc.getHeaderField("Content-Type");
            // 返回頭欄位的不可修改的 Map
            Map<String,List<String>> fields = uc.getHeaderFields();
            // 返回第 n 個頭欄位的鍵
            String headerFieldKey = uc.getHeaderFieldKey(1);
            //  返回第 n 個頭欄位的值
            String headerField = uc.getHeaderField(1);
            System.out.println(contentType);
            System.out.println(fields);
            System.out.println(headerFieldKey);
            System.out.println(headerField);
            //  返回解析為日期的指定欄位的值。
            //long getHeaderFieldDate(String name, long Default)
            //   返回解析為數字的指定欄位的值。
            //int getHeaderFieldInt(String name, int Default)

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

這裡寫圖片描述

配置連線

URLConnection類的保護型別欄位如下:

protected URL url
該欄位指定URLConnection連線的URL。建構函式會在建立URLConnection時設定,此後就不能再改變。

protected boolean connected

  當連線開啟時,該欄位為true。若連線關閉,則為false。沒有直接讀取或改變connected值的方法。任何導致URLConnection連線的方法都會將此變數設為true,包括connect(),getInputStream(),和getOutputStream()。

  任何導致URLConnection斷開的方法都會將此欄位設為false。

  java.net.URLConnection沒有斷開方法,但一些子類,如java.net.HttpURLConnection中存在這樣的方法。

protected boolean allowUserInteraction

  該欄位表示是否允許與使用者互動。預設為false,即不允許互動。該值只能在URLConnection連線前設定。

例:Web瀏覽器可能需要訪問使用者名稱和口令。

protected boolean doInput

  該欄位在URLConnection可用於輸入時為true,否則為false。預設為true。

protected boolean doOutput

  該欄位在URLConnection可用於輸出時為true,否則為false。預設為false。

protected long ifModifiedSince

  該欄位指示了將放置If-Modified-Since首部欄位中的日期(格林威治標準時間1970年1月1日子夜後的毫秒數)。

protected boolean useCaches

  該欄位指定了是否可以在快取可用時使用快取。預設為true,表示快取將被使用;false表示快取不被使用。

每個欄位都有一些相應的方法。

URL getURL()
void setDoInput(boolean doinput)
boolean getDoInput()
void setDoOutput(boolean dooutput)
boolean getDoOutput()
void setUseCaches(boolean usecaches)
boolean getUseCaches()
void setAllowUserInteraction(boolean allowuserinteraction)
boolean getAllowUserInteraction()
void setIfModifiedSince(long ifmodifiedsince)
long getIfModifiedSince()

還有一些方法,這些方法用於定義和獲取URLConnection物件的預設行為:

static boolean getDefaultAllowUserInteraction()
boolean getDefaultUseCaches()
void setDefaultUseCaches(boolean defaultusecaches)
static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)
static void setFileNameMap(FileNameMap map)
static FileNameMap getFileNameMap()

關於超時

Java 1.5增加了如下4個方法,允許查詢和修改連線的超時值。即底層socket在丟擲SocketTimeoutException異常前等待遠端響應時間。
設定獲取讀取的超時值,單位為毫秒。

int getReadTimeout()
void setReadTimeout(int timeout)
設定獲取連線的超時值,單位為毫秒。

int getConnectTimeout()
void setConnectTimeout(int timeout)
這四個方法將0解釋為永不超時。如果超時值為負數。兩個設定方法都會丟擲IllegalArgumentException異常。

配置HTTP首部

客戶端向伺服器傳送請求,不僅會發送請求行,還發送首部。Web伺服器可以根據此資訊向不同客戶端提供不同的頁面,獲取和設定cookie,通過口令設定使用者等等。通過在客戶端傳送和伺服器響應的首部中放置不同的欄位,就可以完成這些工作。

每個URLConnection的具體子類都在首部中設定一些預設的鍵值對(實際上只有HttpURLConnection這樣做,因為HTTP是唯一以這種方式使用首部的主要協議。)

通過以下方法可以設定URLConnection在開啟連線增加HTTP首部:

void setRequestProperty(String key, String value)

此方法只在連線開啟之前開啟,將會丟擲IllegalStateException異常。但該方法僅支援對一個首部設定一個值。

HTTP允許一個熟悉有多個值。各個值之間用逗號隔開。

例:cookie:username=sjq; session=hdfu23asdjf901j;

使用如下方法為首部增加值:

void addRequestProperty(String key, String value)

該方法用於新增某個指定首部欄位的值。

使用如下方法獲取首部欄位:

String getRequestProperty(String key)
Map<String,List<String>> getRequestProperties()

以上方法用於獲取URLConneciton所擁有HTTP首部。

使用URLConnection與伺服器互動

InputStream getInputStream():返回從此開啟的連線讀取的輸入流。

OutputStream getOutputStream():返回寫入到此連線的輸出流。

若只是向伺服器請求資料,則為HTTP請求方法為GET。

若需要向伺服器提交資料,必須在先呼叫setDoOutput(true)。當doOutput屬性為true時,請求方法將由GET變為POST。


    @Test
    public void test3(){
        InputStream in = null;
        try {
            //連線
            URL url = new URL("http://www.baidu.com");
            URLConnection uc = url.openConnection();
            //獲取讀入流
            in = uc.getInputStream();
            //放入快取流
            InputStream raw = new BufferedInputStream(in);
            //最後使用Reader接收
            Reader r = new InputStreamReader(raw);
            //列印輸出
            int c;
            while((c = r.read())>0){
                System.out.print((char)c);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                if(in!=null){
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

這裡寫圖片描述

獲得內容

Object getContent()
該方法實質上與URL類的getContent()方法相同。使用該方法JVM需要識別和理解該內容型別。該方法只用於支援類似HTTP的協議,協議需要對MIME內容型別有較清楚的瞭解。若內容未知,或協議無法理解內容型別,getContent()會丟擲一個UnknowServiceException異常。

Object getContent(Class[] classes)

該方法可以選擇將內容轉換為哪個類物件,以提供資料的不同物件表示。該方法嘗試以classes陣列中某個類的形式返回內容。優先順序就是陣列的順序。若任何一種請求型別都不可用,此方法會返回null。

ContentHandlerFactory

URLConnection類包括一個靜態的ContentHandler。即內容處理器。通過以下方法設定內容處理器工廠。

static void setContentHandlerFactory(ContentHandlerFactory fac)

URLConnection的安全

建立網路連線、讀寫檔案等等存在一些安全限制,URLConnection物件會受到這些安全限制的約束。

Permission getPermission()

該方法返回Permission物件,指出連線此URL所需的許可權。如果沒有所需的許可權(即沒有適當的安全管理器),它就會返回null。

猜測MIME內容型別

static String guessContentTypeFromName(String fname)
根據 URL 的指定 “file” 部分嘗試確定物件的內容型別。

static String guessContentTypeFromStream(InputStream is)
根據輸入流的開始字元嘗試確定輸入流的型別。

HttpURLConnection

java.net.HttpURLConnection類是URLConnection的抽象子類;它提供了一些有助於專門操作http URL的額外方法。

sun.net.www.protocol.http包中也提供了一個HttpURLConnection類。該類實現了抽象的connect()方法。但一般很少直接訪問該類。

獲取HttpURLConnection物件

@Test
void testHttpURLConnection(){
    try {
        URL url = new URL("http:www.baidu.com");
        URLConnection urlConnection = url.openConnection();
        HttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection;
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

請求方法

HTTP協議提供了7中請求方法:

GET
POST
HEAD
PUT
OPTIONS
DELETE
TRACE
通過以下方法設定請求方法:

void setRequestMethod(String method)

若請求不是7個方法的字串,則會丟擲java.net.ProtocolException異常。一般只設置請求方法是不夠的,還需要調整HTTP首部,還要提供訊息體。

以下方法獲取HTTP請求方法

String getRequestMethod()

斷開與伺服器的連線

HTTP的Keep-Alive對Web連線的效能有所提升,允許多個請求和響應通過一個TCP連線連續傳送。

客戶端通過HTTP請求首部包含Connection欄位及Keep-Alive,表示客戶端願意使用Keep-Alive:

  Connection: Keep-Alive

但當使用Keep-Alive時,伺服器不再因為向客戶端傳送最後一個位元組資料就關閉連線。畢竟客戶端還可能傳送另一個請求。因此客戶端需要複雜關閉連線。

Java提供如下方法關閉連線,實際上很少使用該方法:

abstract void disconnect()

獲取請求

如果HTTP響應狀態為4xx(客戶端錯誤)或者5xx(伺服器錯誤),你可以通過HttpUrlConnection.getErrorStream()來檢視伺服器傳送過來的資訊。

InputStream getErrorStream()

例:

InputStream error = ((HttpURLConnection) connection).getErrorStream();

如果HTTP響應狀態為-1,就是出現了連線錯誤。HttpURLConnection會保持連線一直可用,如果你想關閉這個特性,需要把http.keepAlive設定為false:

System.setProperty("http.keepAlive", "false");

Http響應碼

HTTP響應的第一行被稱為訊息響應。該資訊不會被URLConnection的getHeaderFiled()方法讀取。

String getResponseMessage()
返回訊息響應。如:HTTP/1.1 404 Not Found

int getResponseCode()
返回訊息響應碼。如:404。

HttpURLConnection類提供了常見響應碼常量。具體請參考JDK文件。

重定向

預設情況下,HttpURLConnection類會跟蹤重定向。但HttpURLConnection有兩個靜態方法,可以確定是否跟隨重定向。

static void setFollowRedirects(boolean set)
static boolean getFollowRedirects()

  若跟隨,則為true,否則為false。

這兩個是靜態方法,它們會改變該方法後構造的所有HttpURLConnection物件的行為。若安全管理器不允許其改變,則會丟擲SecurityException異常。

也可以對某個HttpURLConnection例項設定是否重定向。

void setInstanceFollowRedirects(boolean followRedirects)

boolean getInstanceFollowRedirects()

流模式

每個傳送給HTTP伺服器的請求都有HTTP首部。首部中有一個Content-type欄位;即請求體中的位元組數。首部位於主體的前面。但是,為了寫入首部,需要知道主體的長度,而在寫首部的時候可能還不知道主題的長度。一般情況下Java對此兩難境地的解決辦法是,對於從HttpURLConnection獲取的OutputStream,快取寫入到此OutputStream中的所有內容,直到流被關閉。到這時,它就知道了主題中有多少位元組,

在請求傳送之前,HttpURLConnetion會把所有需要傳送的資料放到緩衝區裡,不管你是否使用connection.setRequestProperty(“Content-Length”, contentLength);設定了contentLength,當你並行傳送大量的POST請求時,這可能會引起OutOfMemoryExceptions 異常,為了避免這個問題,需要使用如下方法:

void setFixedLengthStreamingMode(int contentLength)

  此方法用於在預先已知內容長度時啟用沒有進行內部緩衝的 HTTP 請求正文的流。

例:

httpConnection.setFixedLengthStreamingMode(contentLength);

但是如果不能事先知道內容的長度,可以使用HttpURLConnection.setChunkedStreamingMode()方法設定為塊狀流模式。在塊狀流模式的情況下,放在塊裡的內容將會被強行傳送出去。下邊的例子將會把傳送的內容按照每塊1KB的大小發送出去。

void setChunkedStreamingMode(int chunklen)

  此方法用於在預先不知道內容長度時啟用沒有進行內部緩衝的 HTTP 請求正文的流。

例:

httpConnection.setChunkedStreamingMode(1024);

快取

預設情況下,Java 1.5不返回任何資料。但通過派生java.net.ResponseCache類的子類,並安裝為系統預設值,就可以建立自己的快取。無論系統合適嘗試通過協議處理器載入新的URL,它將首先在快取中查詢,若快取找到了所需的內容,就不需要連線遠端伺服器了。若快取資料不存在,則下載相應資料,並將其放入快取中。

相關推薦

URLConnection概述

URLConnection是一個抽象類,表示指向URL指定資源的活動連線。 URLConnection類本身依賴於Socket類實現網路連線。一般認為,URLConnection類提供了比Socket類更易於使用、更高階的網路連線抽象。但實際上,大多數程式設計

數據庫---->應掌握的知識點:概述

如何實現 數據 設計 掌握 伸縮性 原理 dbms 存儲 系統 第一部分 DBMS的功能以及實現該功能的原理 數據庫管理系統相關知識 DBMS如何存儲和管理大數據集(有效性和可伸縮性) DBMS是如何實現多用戶同時存取數據的(並發性) 系統出現故障時,DBMS如何保護數

UNIX 系統概述

目錄 數量 標準輸入 線程id 出錯 其他應用 讀取 word 整數 1. UNIX體系結構(UNIX Architecture) 調用內核的接口叫做系統調用(system call,圖1.1中的陰影部分),普通函數庫是建立在系統調用接口的基礎之上。應用(appli

Linux 網絡概述

b2c linu strong art inux 分享 數據鏈路 avi ext OSI參考模型與TCP/IP參考模型如上圖所看到的。OSI的應用層、表示層、會話層相應TCP/IP的應用層;OSI的傳輸層相應TCP/IP的傳輸層。OSI的網絡層相應TCP/IP的網絡層

項目進階 之 集群環境搭建(一)概述

問題 特點 多臺 cpu 好的 content 成了 系統資源 通過 今天我們說一個不是特別新,但近期今年伴隨大數據熱而比較火的一個技術-集群技術。 什麽是集群技術 集群(Cluster)技術是指一組相互犭蟲立的計算機,利用快速通信網絡組

java jvm概述

執行文件 windows 源程序 認識 ava 操作 編譯 編譯器 分層 java jvm 有分層的思想。 java類、.java文件,源文件,源代碼,源程序 編譯器不能把源代碼直接編譯成0101,除非是java語言寫的操作系統。 windows認識的可執行文件

URLConnection/案例

str close exceptio lin () rgs enc pack [] package zuihou; import java.io.BufferedReader; import java.io.FileOutputStream; import java.i

操作系統精髓與設計原理------調度概述

而在 約束 可靠性 關系 理解 負責 能夠 先進先出 之間 前言:操作系統必須為多個進程之間可能有競爭關系的請求分配計算機資源。對處理器而言,可分配的資源是處理器上的執行時間,分配的途徑是“調度”。調度功能必須設計成可以滿足多個目標,包括公平、任何進程都不會產生饑餓、有效的

網絡概述——網絡的分類

方便 沒有 font local 前途 無線電 不同的 cnblogs 無線 計算機網絡的定義: 計算機網絡是把分布在不同地理區域的計算機與專門的外部設備用通信線路互聯成一個規模大、功能強的系統,使用某些通信協議,使眾多的計算機可以方便地互相傳遞信息,共享硬件

功能點方法概述

項目管理 成本 工作量 工業 規模 什麽是功能點方法簡單的說,功能點方法是一種估算軟件項目大小的方法,它是從用戶視角出發,通過量化系統功能來度量軟件的規模,這種度量主要基於系統的邏輯設計。功能點規模度量方法在國際上的應用已經比較廣泛,並且已經取代代碼行成為最主流的軟件規模度量方法。功能點方

第2章 GNS3和PacketTracer網絡模擬器(1)_GNS3概述

下載 功能 安裝位置 ges images 項目目錄 捕獲 png 編寫 1. 安裝和配置GNS3 1.1 GNS3概述 (1)GNS3是一款具有圖形化界面,可運行在多平臺(包括Windows、Linux、Mac OS等)上面的網絡虛擬軟件。 (2)可以在虛擬環境中運行Ci

hadoop概述

str 集群 全文檢索 適合 性能 技術 數據安全 文件 mapreduce 一、hadoop的起源Apache Lucene   開源的高性能全文檢索工具包Apache Nutch   開源的web搜索引擎google的三篇論文   GFS ->

MySQL優化概述

查看 刪除 使用場景 lai 系統 incr 數據 建立 計算 MySQL優化概述 設計: 存儲引擎,字段類型,範式 功能: 索引,緩存,分區。 架構: 主從復制,讀寫分離,負載均衡。 合理SQL: 測試,經驗。 存儲引擎 Create tab

spring之註解(一)概述

dsm 的人 src article service 優缺點 中一 auto 數據 Spring的核心是依賴註入(DI),而依賴註入的基礎是依賴信息的配置。這些配置稱之為元數據。在之前的的學習中。一直採用的是基於xml的配置,這些元數據配置在spring內部被註冊成為B

WebService概述和CXF入門小程序

定義 clas zhang 目的 配置 service組件 ott code 方式 一. 什麽是WedService? WebService不是框架, 甚至不是一種技術, 而是一種跨平臺,跨語言的規範, WebService的出現是為了解決這種需求場景: 不同平臺,

文檔總結(一)——文檔的概述

理解 需要 軟件需求 是否 研究 strong 開發項目 問題 項目開發 寫完文檔後,本來想寫一篇具體的文檔的總結的,後來看大家都寫的具體文檔總結,於是我就想:我還是寫一些跟大家不一樣的東西吧。 所以,我就說說我對各個文檔的宏觀理解吧。

Java核心類庫-IO-NIO概述

字符 java 傳統 ont syn 概述 pan spa 數據 NIO:New IO 從JDK1.4開始提出的,新的IO,可以把一塊磁盤文件映射到內存中,我們再去讀取內存中的數據。 存放在java.nio包中 Java NIO(New IO)是Java1.4版本開始引入的

【數據結構】數據結構的概述

邏輯關系 安排 線性表 markdown 一個 ava auto nbsp log 一、概述 什麽是數據結構:數據:由有限的符號(比如,"0"和"1",具有其自己的結構、操作、和相應的語義)組成的元素的集合。結構:元素之間的關系的集合。數據結構:信息的一種組織方式,其目

java-1概述

javaJava的含義 java是由Sun Nicrosystems公司於1995年5月推出的java面向對象程序設計語言和java平臺的總稱 兩層含義:開發語言 開發平臺java主要特征 簡單 動態 高性能 跨平臺 面向對象 健壯性 安全 多線程 分布式 java是面向對象的語言:

02.18_Java語言基礎(數據類型的概述和分類).avi

技術分享 png src 分類 com 語言 logs 技術 blog 02.18_Java語言基礎(數據類型的概述和分類).avi