關(guān)于 URL幾個不知道的點
01、什么是 URL
為了搞清楚什么是 URL,需求引入別的兩個概念 URI 和 URN。
什么鬼,URL 都沒搞清楚,又來兩個搞不清楚的?別憂慮,我能像變了魔法相同讓咱們把三個都搞清楚。
-
URI = Universal Resource Identifier,中文釋義為一致資源標(biāo)志符
-
URL = Universal Resource Locator,中文釋義為一致資源定位符
-
URN = Universal Resource Name,中文釋義為一致資源名稱
它們之間的聯(lián)系如下圖所示:
這圖啥意思啊,怎樣辦呢?張小敬有問題就去問葛佬,咱不會就去問“維基百科”啊。
URI 能夠分為 URL 和 URN,或者是 URL 和 URN 的結(jié)合體(一起具有 Locator 和 Name)。URN 就好像一個人的姓名,URL 就像一個人的地址。換句話說:URN 確定了身份,URL 供給了找到它的方法。
概念明晰了吧?URI 是一個樸實的句法結(jié)構(gòu),用于指定標(biāo)識 Web 資源的字符串的各個不同部分。URL 是 URI 的一個特例,包含了定位 Web 資源的足夠多的信息。URI 是一致資源標(biāo)識符,而 URL 是一致資源定位符。URL 是 URI 的一種,比方:http://www.itmind.net/。但不是所有的 URI 都是 URL,由于 URI 或許包含一個子集,即一致資源名稱 (URN,命名了資源但不指定如何定位資源),比方說:mailto:qing_gee@163.com。
吧啦吧啦說這么多挺累的,來一發(fā)實例吧,用于獲取 URL 的主機名和端口號。
URL url = new URL("http://www.itmind.net/category/payment-selection/zhishixingqiu-jingxuan/"); System.out.println("host: " + url.getHost()); System.out.println("port: " + url.getPort()); System.out.println("uri_path: " + url.getPath()); // 輸出 // host: www.itmind.net // port: -1 // uri_path: /category/payment-selection/zhishixingqiu-jingxuan/
1)創(chuàng)建java.net.URL目標(biāo)的辦法十分簡略,只需求一行代碼。
URL url = new URL(URL地址);
URL 目標(biāo)是不可變的,由于 URL 類是 final 類型的,這樣的優(yōu)點就是確保它是"線程安全"的。
2)有了java.net.URL目標(biāo)后,就能夠獲取 URL 相關(guān)的主機名、端口、路徑等等。
url.getHost() url.getPort() url.getPath()
02、什么是 URLConnection
URLConnection 是一個抽象類,代表應(yīng)用程序和 URL 之間的通信鏈接。它的實例可用于讀取和寫入此 URL 引證的資源。該類供給了比 Socket 類更易于運用、更高檔的網(wǎng)絡(luò)銜接抽象。
怎樣獲取 URLConnection 目標(biāo)呢?經(jīng)過 URL 目標(biāo)的openConnection()辦法,示例如下。
URL url = new URL("http://www.itmind.net"); URLConnection connection = url.openConnection();
假如 URL 協(xié)議為 HTTP 的話,回來的銜接為 URLConnection 的子類 HttpURLConnection。
有了URLConnection目標(biāo)后,能夠經(jīng)過getInputStream()回來一個 InputStream,由此讀取 URL 所引證的資源數(shù)據(jù)(假如讀取 ASCII 文本則為 ASCII;假如讀取 HTML 文件則為原始 HTML,假如讀取圖像文件則為二進(jìn)制圖片數(shù)據(jù)等)。
咱們來測驗讀取一下小白書院主頁的內(nèi)容,代碼示例如下。
URL url = new URL("http://www.itmind.net"); URLConnection connection = url.openConnection(); try (InputStream in = connection.getInputStream();) { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = newbyte[1024]; int len = -1; while ((len = in.read(buffer)) != -1) { output.write(buffer, 0, len); } System.out.println(new String(output.toByteArray())); } catch (IOException e) { e.printStackTrace(); }
能夠運用try-with-resource獲取InputStream,該類實現(xiàn)了AutoCloseable接口,能夠在內(nèi)容讀取完畢后自動關(guān)閉輸入流。
打印的內(nèi)容如下圖所示(部分):
假如你想讀取某個 URL 的內(nèi)容,上述辦法是一個不錯的計劃,趕快去試試吧!
03、URL 和 URLConnection 的不同
URL 和 URLConnection 最大的不同在于:
-
URLConnection 供給了對 HTTP 頭部的拜訪;
-
URLConnection 能夠配置發(fā)送給某個 URL 的請求參數(shù);
-
URLConnection 不只能夠讀取 URL 定位的資源,還能夠向其寫入數(shù)據(jù)。
獲取 HTTP 頭部的辦法有以下一些:
-
getContentType,回來 Content-type 頭字段的值,即數(shù)據(jù)的 MIME 內(nèi)容類型。若類型不可用,則回來 null。假如內(nèi)容類型是文本,則 Content-type 首部或許會包含一個標(biāo)識內(nèi)容編碼方法的字符集,例如:Content-type:text/html; charset=UTF-8
-
getContentLength(),回來 Content-length 頭字段的值,即內(nèi)容的字節(jié)數(shù)。
-
getContentEncoding(),回來 Content-encoding 頭字段的值,即內(nèi)容的編碼方法(不同于字符編碼方法),例如:x-gzip。
-
getDate(),回來 date 頭字段的值,即請求的發(fā)送時刻。
-
getExpiration(),回來 expires(過期時刻) 頭字段的值。假如回來 0,表明不過期,永久緩存。
-
getLastModified(),回來 last-modified(前次修改日期) 頭字段的值。
代碼示例如下。
URL url = new URL("http://www.itmind.net"); URLConnection connection = url.openConnection(); System.out.println(connection.getContentType()); System.out.println(connection.getContentLength()); System.out.println(connection.getContentEncoding()); System.out.println(connection.getDate()); System.out.println(connection.getExpiration()); System.out.println(connection.getLastModified()); // 輸出 // text/html; charset=UTF-8 // -1 // null // 1566886980000 // 0 // 0
04、最終
利用 URLConnection 還能夠向指定的 URL 請求發(fā)送 POST 請求,但這種作法現(xiàn)已很少有人在用了,所以這篇文章也不打算進(jìn)行介紹了。假如十分感興趣,想自己試一試,能夠在公眾號后臺回復(fù)「666」獲取咱們?yōu)槟憔臏?zhǔn)備的高清帶書簽的 PDF——《Java 網(wǎng)絡(luò)編程(第4版)》,第 7 章對此進(jìn)行了詳細(xì)的介紹。