网络——获取Web数
【0】README
0.1) 本文描述轉(zhuǎn)自 core java volume 2, 旨在理解 “網(wǎng)絡(luò)——獲取Web數(shù)” 的基礎(chǔ)知識(shí);
0.2) for source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter3/URL/URLConnectionTest.java
0.3) 應(yīng)用背景: 為了在 java 程序中訪問(wèn)web server, 你可能希望在更高級(jí)別上進(jìn)行, 而不只是創(chuàng)建套接字連接和發(fā)送 HTTP 請(qǐng)求;
0.4) 本文源代碼用到了 Base64Encode 編碼器,參見: http://blog.csdn.net/pacosonswjtu/article/details/50614466
【1】URL 和 URI(統(tǒng)一資源定位符(Uniform Resource Locator, URL) 和統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier, URI))
1)URL和 URLConnection類:封裝了大量復(fù)雜的實(shí)現(xiàn)細(xì)節(jié), 這些細(xì)節(jié)涉及如何從遠(yuǎn)程站點(diǎn)獲取信息;
1.1)如可以用一個(gè) string 創(chuàng)建一個(gè) URL 對(duì)象:
URL url = new URL(urlString);
1.2)如果只是想獲得該資源的內(nèi)容, 可以使用 URL 類中的openStream 方法:
URL url = new URL(urlName);
InputStream stream = url.openStream();
Scanner in = new Scanner(stream);
2)java.net 包對(duì) 統(tǒng)一資源定位符(Uniform Resource Locator, URL) 和統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier, URI) 做了非常有用 的區(qū)分;
2.1)URI和URL的區(qū)別: (干貨——URI和URL的區(qū)別)
- 2.1.1)URI: URI 是一個(gè)純粹的語(yǔ)法結(jié)構(gòu), 包含用來(lái)指定web 資源的字符串的各種組成部分; (干貨——URI定義)
- 2.1.2)URL: URL 是URI的一個(gè)特例, 它包含了用于定位Web 資源的足夠信息, 其他URI, 比如 mailto:tang@gmail.com 就不屬于定位符, 因?yàn)楦鶕?jù)該標(biāo)識(shí)符我們無(wú)法定位任何數(shù)據(jù)。 像這樣的URI 我們稱之為 URN(Uniform Resource name, 統(tǒng)一資源名稱);(干貨——URL定義)(干貨——URN-統(tǒng)一資源名稱)
2.2) 在java 類庫(kù)中, URI 類不包含任何用于訪問(wèn)資源的方法, 它唯一作用就是解析; 相反, URL類可以打開一個(gè)到達(dá)資源的流: 所以 URL類只能作用于 那些 java 類庫(kù)知道該如何如理的模式,如 http: , https, ftp:, 本地文件系統(tǒng)(file:), jar 文件(jar:);
3)URI詳解:
3.1)URI 規(guī)范給出了標(biāo)記這些標(biāo)識(shí)符的規(guī)則,一個(gè) URI 具有以下句法:
[scheme:]schemeSpecificPart【#fragment】
3.2)上式中, […]表示可選部分,且 : 和 # 可以被包含在標(biāo)識(shí)符內(nèi);
- 3.3)絕對(duì)URI 和 相對(duì) URI: 包含scheme: 部分 的 URI 稱為絕對(duì)URI ,否則是相對(duì)URI; (干貨——絕對(duì)和相對(duì)URI)
- 3.4)不透明URI: 如果絕對(duì)URI 的 schemeSpecificPart 不是以 / 開頭的,稱為不透明的;如, mailto:tang@gmail.com (干貨——不透明URI)
- 3.5)分層URI: 所有絕對(duì)的透明URI 和所有相對(duì)的URI 都是分層的, 如: http://www.baidu.com/index.html (干貨——分層URI)
3.6)一個(gè)分層URI 的schemeSpecificPart 具有以下結(jié)構(gòu):
[//authority][path][?query]
3.6.1)對(duì)于那些基于服務(wù)器的URI, authority 部分具有以下形式:
[user-info@]host[:port] , 而port必須是整數(shù);
4)URI的作用: (干貨——URI的作用)
4.1)URI 類的作用之一: 解析標(biāo)識(shí)符并將它分解成各種不同的組成部分, 你可以用如下方法讀取他們:
getScheme
getSchemeSpecificPart
getAuthority
getUserInfo
getHost
getPort
getPath
getQuery
getFrament4.1)URI的另一個(gè)作用: (干貨——URI 的絕對(duì)化 和 相對(duì)化)
- 4.1.1)組成絕對(duì)URI:處理絕對(duì)標(biāo)識(shí)符和相 對(duì)標(biāo)識(shí)符。 如果存在一個(gè)絕對(duì)URI: http://www.baidu.com/java/net/index.html; 和 一個(gè)相對(duì)URI: ../../java/net/index.html#socket(); 那么用它們組合成一個(gè)絕對(duì)URI: http://www.baidu.com/java/net/index.html#socket()
- 4.2)與以上過(guò)程相反的是相對(duì)化URI: 假設(shè)一個(gè)URI: http://docs.mycompany.com/api 和另一個(gè)URI:http://docs.mycompany.com/api/java/lang/String.html; 那么相對(duì)化之后的URI 就是: java/lang/String.html;
4.3) URI 類同時(shí)支持以上兩個(gè)操作: (干貨——URI的絕對(duì)化 和 相對(duì)化)
relative = base.relativize(combined);
combined = base.resolve(relative);
【2】使用URLConnection獲取信息
1)引入 URLConnection的目的: 如果想從某個(gè)web 資源獲取更多信息, 應(yīng)該使用 URLConnection 類,通過(guò)它能夠得到比 URL類更多的控制功能; (干貨——推薦使用URLConnection ,它能夠得到比 URL類更多的控制功能)
2)如何操作一個(gè) URLConnection對(duì)象:
step1) 調(diào)用 URL 類中的openConnection方法:
URLConnection connection = url.openConnection();
step2)使用以下方法來(lái)設(shè)置任意的請(qǐng)求屬性:
setDoInput
setDoOutput
setIfModifiedSince
setUseCaches
setAllowUserInteration
setRequestProperty
setConnectTimeout
setReadTimeoutstep3) 調(diào)用 connect方法連接遠(yuǎn)程資源:
connection.connect();
step4)與服務(wù)器建立連接后, 可以查詢頭信息。
- step4.1) getHeaderFieldKey 和 getHeaderField 兩個(gè)方法枚舉消息頭的所有字段;
- step4.2) getHeaderFields 方法返回一個(gè)包含了消息頭中所有字段的標(biāo)準(zhǔn)Map對(duì)象;
step4.3) 為了方便起見, 以下方法可以查詢各個(gè)標(biāo)準(zhǔn)字段:
getContentType
getContentLength
getContentEncoding
getDate
getExpiration
getLastModified
step5)最后,訪問(wèn)資源數(shù)據(jù)。
- step5.1)使用 getInputStream 方法獲取一個(gè)輸入流用以讀取信息;
Attention)一些coders 在使用 URLConnection 類的過(guò)程中形成了錯(cuò)誤的觀念, 它們認(rèn)為 URLConnection 類中的 getInputStream 和 getOutputStream 方法與 Socket 類中的這些方法相似,這是錯(cuò)誤的想法; (干貨——一些coders 在使用 URLConnection 類的過(guò)程中形成了錯(cuò)誤的觀念)
3)URLConnection類中的一些方法:有幾個(gè)方法可以在與server 建立連接之前設(shè)置連接屬性,最重要的方法是 setDoInput 和 setDoOutput方法;
- 3.1) 如果想要獲得輸出流:則 connection.setDoOutput(true);
- 3.2)setIfModifiedSince 方法: 用于高速連接你只對(duì)自某個(gè)特定日期以來(lái)被修改過(guò)的數(shù)據(jù)感興趣;
- 3.3)setUseCaches 和 setAllowUserInteraction 方法:這兩種方法只作用于Applet;
- 3.4) setUseCaches 方法: 用于命令瀏覽器首先檢查它的緩存;
- 3.5)setAllowUserInteraction方法: 用于在訪問(wèn)有密碼保護(hù)的資源時(shí)彈出對(duì)話框;
- 3.6)總覽全局的方法 setRequestProperty方法: 它可以用來(lái)設(shè)置對(duì)特定協(xié)議起作用的任何 “鍵值對(duì)”;
4)看個(gè)荔枝:如果你想訪問(wèn)一個(gè)由密碼保護(hù)的web 頁(yè)面, 按如下步驟操作:
step1) 將用戶名,,冒號(hào), 密碼連接在一起:
String input = username + “:” + password;
step2) 計(jì)算上一步驟得到的 Base64 編碼;Base64 編碼用于將字節(jié)序列編碼成可打印的ASCII字節(jié)序列; (干貨——Base64編碼)
String encoding = base64Encode(input);
step3)調(diào)用 setRequestProperty 方法,設(shè)置name參數(shù)的值為 Authorization , value設(shè)置為 Basic + encoding;
connection.setRequestProperty(“Authorization”, “Basic” + encoding);
5)一旦調(diào)用了 connect方法, 就可以查詢響應(yīng)頭信息;
step1)枚舉所有相應(yīng)頭的字段:
String key = connnection.getHeaderFieldKey(n); // 可以獲得第n個(gè)鍵,n從 1開始;
step2)得到第n個(gè)值;
String key = connnection.getHeaderField(n); // 可以獲得第n個(gè)鍵,n從 1開始;
step3) getHeaderFields 方法: 返回一個(gè) 封裝類響應(yīng)頭字段的Map 對(duì)象;
Map<String, List< String>> headers = connection.getHeaderFields();
6) 為簡(jiǎn)單起見: java 提供了6個(gè)方法用以訪問(wèn)最常用的消息頭類型的值, 并在需要的時(shí)候?qū)⑵滢D(zhuǎn)換為 數(shù)值類型,見下表所示: (干貨——java 提供了6個(gè)方法用以訪問(wèn)最常用的消息頭類型的值)
7)看個(gè)荔枝(如何從web server 讀取數(shù)據(jù))
總結(jié)
以上是生活随笔為你收集整理的网络——获取Web数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大太监大结局 大太监的结局是什么
- 下一篇: 网络——Base64Encode(转:自