URL的全稱是Uniform Resource Locator,意思是統一資源定位符,俗稱網絡地址或網址。網絡上的每一個文件及接口,都有對應的URL網址,它規定了其餘設備如何經過一系列的路徑找到本身,猶如網購的包裹一路送至收貨地址所描述的地點。現實生活中的通信地址,通常遵循固定的格式,好比「××省××市××區××小區×××」;網絡地址也有相應的命名規則,好比新華網的首頁地址爲「http://www.news.cn」,固然該地址比較簡單,還能造出更復雜的URL如「http://www.news.cn:8080/Public/GetValidateCode?time=123#index」(該網址純屬虛構)。雖然普通用戶平時上網只消打開網頁接着在各種連接之間跳來跳去,可是做爲程序員必須弄清楚這些連接地址的格式涵義,這樣才能學好網絡通訊的編程開發。仍以網址「http://www.news.cn:8080/Public/GetValidateCode?time=123#index」爲例,該URL包含了網絡地址的各項組成部分,具體細節以下圖所示。html
接下來對上圖的URL字符串補充詳細說明,從左到右依序介紹以下:
一、最開頭的http表示該地址採用的網絡協議,它的全稱是「Hypertext Transfer Protocol」,意思是超文本傳輸協議。除了http,常見的網絡協議還有https、ftp、file、telnet等等。
二、協議後面越過兩個斜杆,緊跟着的是該網址所在的域名,也叫主機名稱。這塊早已爲大衆所熟知,除了新華網的www.news.cn,還有中央電視臺的www.cctv.com、人民日報的www.people.com.cn等等。
三、域名後面以冒號隔開的數字叫作端口號,像http協議默認的端口號是80。若是該網址採起默認的端口,就沒必要寫明端口數字;若是該網址使用了非默認的端口,好比http服務搭建在8080端口之上,就必須在URL中寫明8080。
四、域名加上端口號,組成了URL的受權部分,即網址的入口。
五、受權部分的右邊包括斜杆在內、問號以前的一長串字符,表示具體的網絡路徑,猶如操做系統裏面的文件目錄。
六、問號以後、井號以前的部分,是以等號隔開的請求參數,各參數之間以「&」分隔,具體格式形如「參數A名稱=A參數值&參數B名稱=B參數值&參數C名稱=C參數值」。請求參數中的參數值容許變化,網絡服務將按照指定的數值返回相應的結果數據。
七、網絡路徑加上請求參數,組成了URL的文件名稱,有了文件名就能訪問該URL所表達的網絡資源。
八、井號以後的字串爲引用位置,假設一個網頁很長很長,打開後默認顯示網頁的頂部,形成用戶下拉網頁找到某塊區域有點麻煩。而引用位置先給各區域作個編號,而後在URL末尾帶上該位置的編號,因而網頁打開後會自動滾到指定位置的區域,從而方便了用戶的瀏覽操做。
搞清楚了URL各段部分的做用,有助於後續的網絡編程工做。就網址訪問而言,Java提供了同名的網址工具URL,該工具類不偏不倚正好名叫URL,其構造方法的輸入參數即爲網址字符串,此後的HTTP訪問操做皆有賴於URL對象。URL工具經常使用的方法包括但不限於下列幾種:
getProtocol:獲取URL對象採用的網絡協議。
getHost:獲取URL對象的域名(主機名稱)。
getDefaultPort:獲取URL對象的默認端口。http協議的默認端口號是80,ftp協議的默認端口號是21,https協議的默認端口號是443。
getPort:獲取URL對象的指定端口(若不顯式指定則返回-1)。
getAuthority:獲取URL對象的受權部門(由域名和指定端口組成)。
getPath:獲取URL對象的路徑(不包括域名)。
getQuery:獲取URL對象的請求參數。
getFile:獲取URL對象的文件名(由路徑和請求參數組成)。
getRef:獲取URL對象的引用位置。
openConnection:打開URL對象的網絡鏈接,並返回URLConnection鏈接對象。不管是接口調用,仍是上傳下載,都依賴於這裏的鏈接對象。程序員
一個完整的網址字符串,包含了蠻多的地址信息,一個字符都錯不得。天然程序員很關心網址到底有哪些校驗辦法,能夠支持判斷某個網址是合法請求仍是非法請求。首先是域名的合法性校驗,Java提供了專門的網絡地址工具InetAddress,調用該工具的靜態方法getByName,可以得到指定域名的網絡地址對象,具體的方法調用代碼示例以下:編程
// 根據域名或IP得到對應的網絡地址對象 InetAddress inet = InetAddress.getByName(host);
以後調用網絡地址對象的如下方法,便可獲取相應的網絡地址信息:
getHostAddress:獲取網絡地址對象的IP地址。
getHostName:獲取網絡地址對象的域名。
isReachable:檢查對方主機是否能連得上。但該方法不可靠,由於可能因爲存在防火牆致使返回false。
可見儘管InetAddress提供了isReachable方法用於檢測域名的連通性,但該方法並不總能奏效。那麼退而求其次,只要校驗域名的格式是否正確便行;這樣的話,在調用getByName方法之時,增長捕捉未知域名異常UnknownHostException;一旦捕捉到該異常,就認爲當前域名是非法域名。此時域名的合法性校驗代碼變成了下面這樣:數組
// 測試域名的可用信息。返回true表示域名合法,返回false表示域名非法 private static boolean testHost(String host) { try { // 根據域名或IP得到對應的網絡地址對象 InetAddress inet = InetAddress.getByName(host); } catch (UnknownHostException e) { // 若是host字符串並不是合法的域名/IP,則getByName方法會扔出「未知的域名異常」 e.printStackTrace(); return false; // 返回false表示該字符串不是合法的域名/IP } return true; // 返回true表示該字符串是合法的域名/IP }
另外一個值得注意的地方是請求參數中的參數值編碼,顯然URL格式存在部分保留字符,包括冒號、斜杆、問號、井號等等,這些字符不該直接出如今Query部分的參數值當中,故而須要對參數值裏面的保留字符進行轉義。常見字符對應的URL轉義符以下圖所示:網絡
除了保留字符之外,中文字符同樣須要轉義,好比「你」要轉爲「%E4%BD%A0」。原始字符的轉義過程也稱做URL編碼,反過來則有反轉義過程,即將轉義後的字符恢復爲原始字符,反轉義過程也稱做URL解碼。Java同時提供了對應的URL編碼工具URLEncoder,以及URL解碼工具URLDecoder,其中URL編碼的方法調用示例以下:工具
// 得到URL編碼後的轉義字符串 String encoded = URLEncoder.encode(origin);
URL解碼的方法調用示例以下:測試
// 得到URL解碼後的原始字符串 String origin = URLDecoder.decode(encoded);
更多Java技術文章參見《Java開發筆記(序)章節目錄》編碼