1. 程式人生 > >Java網路程式設計之HttpURLConnection

Java網路程式設計之HttpURLConnection

這裡寫圖片描述

從上圖,可知HttpURLConnection是URLConnection類的子類,先了解下URLConnection.

URLConnection類:

  • 描述:

    1. 是從Url建立的,並且用於訪問URL指向的資源的通訊連線。

    2. 這個抽象類的工作是通過底層協議(例如http或者https)來處理。

    3. URLConnection是應用程式和Url之間通訊的類的超類。

    4. 這類物件可以讀取和寫入Url所指向的資源。

  • 從URL建立其物件到讀寫URL指向的資源,進行了以下步驟:

    1. 通過URL呼叫openConnection()來建立物件

    2. 設定一般引數和請求屬性

    3. connection()來實際連線到遠端物件

    4. 若是遠端物件可用,則可以訪問遠端物件的Header( 標頭)和content(內容)

  • 對以上4個步驟,詳細描述如下:

    1. 建立方式:

         url.openConnection();
      
    2. 修改引數的方法:

         setAllowUserInteraction()
         setDoInput()
         setDoOutput()
         setIfModifiedSince()
         setUseCaches()
      
    3. 修改Request的屬性的方法:

       setRequestProperty()
      

      總結:以上每個set()都有對應的get()獲取到對應值。設定哪些引數和request的屬性都是協議指定的。

    4. 設定一些預設配置的方法:

         setDefaultAllowUserInteraction 
         setDefaultUseCaches.
      
    5. 在連線遠端物件後(即呼叫connection()),用於獲取內容和header的方法:

       getContent
       getOutputStream
       getHeaderField
       getInputStream 
      
    6. 一些頻繁訪問header的方法:

        getContentEncoding
        getContentLength
        getContentType
        getDate
        getExpiration
        getLastModifed 
      
    7. 釋放相關的網路資源:

      呼叫getInputStream()或getOutputStream(),需再呼叫close()。

      通常情況下,可以忽略預連線的引數和一般請求屬性(簡單理解:使用 get請求,不設定引數,request 屬性)。

      對於大多數客戶端(使用者):需注意這兩個getInputStream() 和getContent()。它們很方便訪問到Url所指向的資源(簡單理解:通過這兩個方法可以讀取到伺服器上的資料)。

  • 其API:

    • addRequestProperty(String key, String value) : 新增一個key-value形式的Request屬性

    • connect():若是url的通訊連線,將開啟到此Url所指向資源的通訊連線。

    • setRequestProperty(String key, String value):設定request 的屬性

    • setUseCaches(boolean usecaches):設定true,允許協議使用快取

    • setReadTimeout(int timeout) : 將讀超時設定為指定的超時值,以毫秒為單位。

    • setIfModifiedSince(long ifmodifiedsince):設定從第幾個物件開始獲取(有些協議支援跳過物件獲取)

    • setFileNameMap(FileNameMap map): 設定 FileNameMap。

    • setDoOutput(boolean dooutput): 設定true,允許新增資料。post請求需要用到

    • setDoInput(boolean doinput): 設定true,允許從伺服器讀取資料

    • setAllowUserInteraction(boolean allowuserinteraction):設定true,允許使用者互動的上下文對此Url進行操作。(設定為true,伺服器可以獲取request中coockie.loaction等等)

    • setConnectTimeout(int timeout): 設定一個指定的超時值(以毫秒為單位)

    • setContentHandlerFactory(ContentHandlerFactory fac): 設定應用程式的 ContentHandlerFactory。

    • getxxx()與setxxx()相對應:這裡省略

HttpURLConnection類:

  • 描述:

    1. 一個URLConnection子類,提供一些特有附加功能對於Http協議。

    2. 每個HttpURLConnection物件是用於單個請求,但可以與其他HttpURLConnection物件共享Http伺服器的底層網路連線。

    3. 對於共享的網路連線,在HttpURLConnection的InputStream (或者 OutputStream)呼叫close()來釋放網路資源是沒有效果的。

    4. 若是不需要連線伺服器,則呼叫disconnect() 來關閉底層的socket,釋放資源.

    5. htttp協議處理一些訪問系統資料的設定。例如代理設定及各種其他設定

  • 其特有的API(除開繼承父類的外):

    • disconnect(): 解除連線

    • getPermission():返回一個許可權物件,其代表建立此物件表示的連線所需的許可權。

    • setRequestMethod(String method):設定請求方式,例如GET POST HEAD OPTIONS PUT DELETE TRACE

    • getRequestMethod():獲取request的請求方式

    • usingProxy():使用代理模式連線

    • getErrorStream() :獲取到錯誤流

    • getFollowRedirects() :自動執行Http重定向的boolean值

    • getHeaderField(int n) :返回第n個header的值

    • getHeaderFieldKey(int n) :獲取第n個headder的key

    • getHeaderFieldDate(String name, long Default) :返回解析為日期的指定欄位的值。

    • getResponseCode() :獲取狀態碼

    • getResponseMessage():獲取與來自伺服器的響應程式碼一起返回的 HTTP 響應訊息(如果有)。

    • setChunkedStreamingMode(int chunklen) :在不知道內容長度前提下,設定流輸出時的儲存塊長度

    • setFixedLengthStreamingMode(int contentLength) :在知道內容長度前提下,設定流輸出的固定內容長度

    • setFollowRedirects(boolean set):設定true,允許自動執行Http重定向

    • setInstanceFollowRedirects(boolean followRedirects) :設定此 HttpURLConnection 例項是否應該自動執行 HTTP 重定向(響應程式碼為 3xx 的請求)。

  • 使用案例 :

    • GET使用方式:
      先建立HttpURLConnection物件,設定Header( 標頭 ):

      /**
      * 建立httpUrlConnection物件,指定request的屬性
      *
      * @param url
      * @return
      */
      public HttpURLConnection createConnection(String url) {
         HttpURLConnection urlConnection = null;
         try {   
               //建立其物件
               urlConnection = (HttpURLConnection) new URL(url).openConnection();
      
               //設定連線時間,10秒
               urlConnection.setConnectTimeout(10 * 1000);
               urlConnection.setReadTimeout(10 * 1000);
      
               //資料編碼格式,這裡utf-8
               urlConnection.setRequestProperty("Charset", "utf-8"); 
      
               //新增cookie,cookie規則需開發者自定
               urlConnection.setRequestProperty("Cookie", Constants.COOCKIE_KEY + token); 
      
              //設定返回結果的型別,這裡是json
               urlConnection.setRequestProperty("accept", "application/json"); 
      
               //這裡設定post傳遞的內容型別,這裡json
               urlConnection.setRequestProperty("Content-Type", "application/json");
      
      
          } catch (Exception e) {
              e.printStackTrace();
          }
          return urlConnection;
      }

      從伺服器響應資料,獲取其內容轉成String型別的資料:

      /**
      * 獲取HttpUrlConnection的返回內容
      *
      * @param urlConnection
      * @return
      */
      public String getStreamContent(HttpURLConnection urlConnection) {
         ByteArrayOutputStream byteArrayOutputStream = null;
         BufferedInputStream bufferedInputStream = null;
         String result = null;
      
         try {
              //開啟客戶端與Url所指向的資源的網路連線
              urlConnection.connect();
      
              if (200 == urlConnection.getResponseCode()) {//HTTP_OK 即200,連線成功的狀態碼
                  if (urlConnection.getContentLength() > 0) {
                         bufferedInputStream = new  
                             BufferedInputStream(urlConnection.getInputStream());
                         byteArrayOutputStream = new ByteArrayOutputStream();
                         //httpUrlConnection返回傳輸位元組的長度,建立一個byte 陣列。
                         byte[] b = new byte[urlConnection.getContentLength()];
                         int length;
                         while ((length = bufferedInputStream.read(b)) > 0) {
                             byteArrayOutputStream.write(b, 0, length);
                         }
                        result = byteArrayOutputStream.toString("utf-8");
                  }
             }
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               try {
                   if (byteArrayOutputStream != null) {
                         byteArrayOutputStream.close();
                    }
                   if(bufferedInputStream!=null){
                          bufferedInputStream.close();
                   }
                  if (urlConnection != null) {
                        //解除連線,釋放網路資源
                       urlConnection.disconnect();
                  }
               } catch (Exception e) {
                    e.printStackTrace();
              }
      
        }
         return result;
      }
    • POST使用方式:
      Post請求方式是需要新增Body的,需要傳遞資料到伺服器的。建立其物件和讀取伺服器返回資料的操作都一樣,比GET請求方式多一步新增資料操作: 這裡傳遞一個json資料型別的資料

      //設定連線配置
      HttpURLConnection httpURLConnection = createConnection(url2);
      //新增傳遞的引數
      ddParameter(httpURLConnection, jsonObject);
      //獲取返回資料
      String result = getStreamContent(httpURLConnection);
      
      /**
      * 新增http引數
      *
      * @param urlConnection
      * @param jsonObject
      */
      public void addParameter(HttpURLConnection urlConnection, JSONObject jsonObject) {
        try {
             //設定post請求方式
             urlConnection.setRequestMethod("POST");
             //允許往流中寫入資料
             urlConnection.setDoOutput(true);
            //藉助BufferedOutputStream提高速度
             OutputStream outputStream = new    
                            BufferedOutputStream(urlConnection.getOutputStream()); 
      
             byte[] body = jsonObject.toString().getBytes("utf-8");
             outputStream.write(body, 0, body.length);
             //重新整理資料到流中
             outputStream.flush();
             //關閉流
            outputStream.close();
      } catch (Exception e) {
          e.printStackTrace();
      }
      }
    • 衍生點:
      HTTP請求是有Header和Body構成,Body是傳遞到伺服器上的資料(Post會用到),Header是標頭,包 含一些Coockie,傳遞的資料的編碼格式,響應的資料的編碼格式,Accept格式,Keep-Alive等等。

      這裡是一個簡單的Request Header包含的資訊:

      Host                    localhost:8080
      Accept                  text/html,application/xhtml+xml,application/xml;q=0.9
      Accept-Language         fr,en-gb;q=0.7,en;q=0.3
      Accept-Encoding         gzip,deflate
      Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7
      Keep-Alive              300

相關推薦

Java網路程式設計HttpURLConnection

從上圖,可知HttpURLConnection是URLConnection類的子類,先了解下URLConnection. URLConnection類: 描述: 是從Url建立的,並且用

Java網路程式設計Socket

原文博主禁止轉載,不過我還是希望把一些關鍵的地方筆記下來,閱讀請移步 原文 以下是學習之後的個人筆記 一、Socket通訊基本例項   通過伺服器-客戶端模式引入Socket通訊 伺服器端 package cn.itcast.net; import java.io

Java網路程式設計URL和URI

URL和URI URL可以唯一地標識一個資源在Internet上的位置。URL是最常見的URI URI URI的結構: 模式:模式特定部分 常見的模式有: data file ftp http mailto magnet teln

Java網路程式設計Socket通訊(一)

       最近在學習Java網路程式設計,之前聽說過,但是一直都沒有認真瞭解過。這幾天突然來了興致,覺得很神奇,忽然就想要了解下具體是什麼個情況。         Socket通常也稱作"套接字",用於描述IP地址和埠,是一個通訊鏈的控制代碼。在Internet上的主機

Java網路程式設計URLEncode和URLDecode工具類

import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; public class EncodeTest {

JAVA網路程式設計模擬表單提交

這一篇部落格是對上一篇《JAVA網路程式設計之獲取網路資源》的擴充,這一篇將使用HttpURLConnection來模擬一個表單的提交。在B/S架構的系統中,請求時通過瀏覽器與服務端進行互動的,提交請求引數時使用form表單進行提交,但是有很多時候,我們需要在程

Java網路程式設計Netty拆包和黏包-yellowcong

Netty中,解決拆包和黏包中,解決方式有三種 1、在每個包尾部,定義分隔符,通過回車符號,或者其他符號來解決 2、通過定義每個包的大小,如果包不夠就空格填充 3、自定義協議的方式,將訊息分為訊息頭和訊息體,在訊息頭中表示出訊息的總長度,

Java 網路程式設計 TCP協議

TCP協議 (伺服器端程先啟動,等待客戶端連線)   TCP協議是面向連線的通訊協議,即在傳輸資料前先在傳送端和接收端建立邏輯連線,然後再傳輸資料 保證傳輸資料的全性安,檔案資料不易丟失   在JDK中提供了兩個類用於實現TCP程式,一個是ServerSocket類,用於表示伺

java網路程式設計Netty實戰資料通訊(七)

Netty最佳實戰資料通訊 1 分析       我們需要了解下在真正專案應用中如何去考虛Netty的使用,大體上對於一引數設定都是根據伺服器效能決定的。這個不是最主要的。       我們要考慮的問題是兩臺機器(甚至多臺)使用Netty的怎樣進行通訊,我

java網路程式設計Netty流資料的傳輸處理(五)

Netty流資料的傳輸處理 Socket Buffer的缺陷       對於例如TCP/IP這種基於流的傳輸協議實現,接收到的資料會被儲存在socket的接受緩衝區內。不幸的是,這種基於流的傳輸緩衝區並不是一個包佇列,而是一個位元組佇列。這意味著,即使

java網路程式設計TFTP(一)

** TFTP簡單檔案傳輸協議 ** TFTP使用了UDP套接字,效率比較高,但是也要求TFTP為資料傳輸的不可靠負責。 TFTP伺服器在69埠上監聽到來的資料包,客戶端使用一個隨機的埠號 TFTP作用:許多無盤工作站使用TFTP來載入它們需要的來

Java網路程式設計多執行緒Client-Server

前面廢話過了,現在就直接看程式碼吧! ThreadedClient.java package exercise01; import java.io.*; import java.net.*; public class ThreadedClient { privat

java網路程式設計下載檔案通過多執行緒分塊下載(二)

importjava.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConn

Java網路程式設計單執行緒下載檔案設定顯示進度(一)

下載檔案的時候,如果為了使用者友好,都會給予進度條提醒使用者,那麼怎麼做呢? 其實很簡單,首先獲取伺服器檔案的大小urlConnection.getContentLength(),然後在讀取檔案過程計算檔案百分比增長即可 /** * 檔案下載工具 by sam on

Java網路程式設計獲取IP地址:InetAddress類

示例程式碼: /* * 網路通訊的第一個要素:IP地址。通過IP地址,唯一的定位網際網路上一臺主機 * InetAddress:位於java.net包下 * 1.InetAddress用來代表IP地址。一個InetAdress的物件就代表著一個IP地址 * 2.如

Java網路程式設計InetAddress類

InetAddress類是JAVA中用於描述IP地址的類,它在java.net包中。在JAVA中分別用Inet4Address和Inet6Address類來描述IPv4和IPv6的地址。這兩類都是InetAddress的子類。由於InetAddress沒有public的構造方

java網路程式設計AIO/NIO2.0(三)

概念理解       AIO程式設計,在NIO基礎之上引入了非同步通道的概念,並提供了非同步檔案和非同步套接字通道的實現,從而在真正意義上實現了非同步非阻塞,之前我們學習的NIO只是非阻寒而並非非同步。而AIO它不需要通過多路複用器對註冊的通道進行輪詢操作即可

Java網路程式設計流的詳解

前言 大部分網路程式做的事情就是接受輸入併產生輸出。讀伺服器傳送過來的資料與讀取本地檔案的資料並沒有多大的區別,同時伺服器將資料傳送給客戶端與寫資料到本地檔案也很像。 Java的IO操作基於streams實現的。輸入流讀資料,輸出流寫資料。 該系列文

java 網路程式設計UDP

網路程式設計(UDP傳輸)*1.傳送Send* 建立DatagramSocket, 隨機埠號* 建立DatagramPacket, 指定資料, 長度, 地址, 埠* 使用DatagramSocket傳送DatagramPacket* 關閉DatagramSocket* 2.接

JAVA網路程式設計UDP通訊的實現步驟

與TCP相比,UDP是一種無連線的傳輸層協議,提供面向事務的簡單不可靠資訊傳送服務。UDP通訊主要用到兩個類DatagramPacket和DatagramSocket,下面分別介紹。1、DatagramSocket此類表示用來發送和接收資料報包的套接字。資料報套接字是包投遞服