亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Java網絡編程之URI、URL研究(下)

2019-11-18 15:41:05
字體:
來源:轉載
供稿:網友
Java網絡編程之URI、URL研究(下)(圖一)
  在上個專題《java網絡編程之URI、URL研究(上)》中我們介紹了URI、URL的慨念和體系結構,以及如何使用URI在本文中我將繼續向大家介紹如何使用URL和MIME(多用途的網際郵件擴充協議)的概念以及它如何與URL發生聯系的。


  使用URL

  網絡API通過提供URL類讓我們能在源代碼層使用URL。每一個URL對象都封裝了資源的標識符和協議處理程序。前面的技巧顯示了獲得URL對象的途徑之一是調用URI對象的toURL()方法。但是這種選擇不一定方便(為什么在需要URL對象的時候必須建立URI對象呢?)。作為代替,你可以調用URL構造函數來建立URL對象。你也可以調用URL的方法來提取URL的組件,打開一個輸入流(input stream)從資源中讀取信息,獲得某個能方便檢索資源數據的對象的引用,比較兩個URL對象中的URL,獲得到資源的連接對象,該連接對象答應代碼了解(并寫入)更多的資源的信息。

  URL類有六個構造函數。其中最簡單的是URL(String url),它有一個String類型的參數,把URL分解為自己的組件,并把這些組件存儲在一個新的URL對象中。假如某個URL沒有包含協議處理程序或該URL的協議是未知的,其它的五個構造函數會產生一個java.net.MalformedURLException對象。
下面的代碼片斷演示了使用URL(String url)建立一個URL對象,該對象封裝了一個簡單的URL組件和http協議處理程序。

URL url = new URL ("http://www.informit.com");
  一旦擁有了URL對象,你就可以使用getAuthority()、getDefaultPort()、 getFile()、 getHost()、 getPath()、getPort()、 getPRotocol()、getQuery()、getRef()和getUserInfo(). The getDefaultPort()等方法提取各種組件。假如URL中沒有指定端口的部分,getDefaultPort()方法返回URL對象的協議處理程序使用(資源定位)的默認端口。getFile()方法返回路徑和查詢組件的結合體。getProtocol()方法返回決定資源的連接類型(例如http、mailto、FTP)的協議的名稱。getRef()方法返回URL的部分片斷(我們所知道的引用)。最后,getUserInfo()方法返回授權機構組件的用戶信息部分。在這些URL組件提取方法中,假如某些組件不存在(假如沒有給URL對象的協議處理程序指定默認的端口,它也返回-1),這些方法就返回null或-1。

  作為這些組件提取方法的補充,你還可以調用openStream()方法檢索java.io.InputStream引用。使用這種引用,你可以用面向字節的方式讀取資源。

  列表4是URLDemo1的源代碼。該程序從命令行參數建立了一個URL對象,調用URL組件提取方法來檢索該URL的組件,調用URL的openStream()方法打開與資源的連接并返回一個用于從資源讀取字節數據的InputStream引用,讀取/打印這些字節,關閉輸入流。

  列表4: URLDemo1.java

// URLDemo1.java
import java.io.*;
import java.net.*;

class URLDemo1
{
public static void main (String [] args) throws IOException
{
if (args.length != 1)
{
System.err.println ("usage: java URLDemo1 url");
return;
}

URL url = new URL (args [0]);

System.out.println ("Authority = "+ url.getAuthority ());
System.out.println ("Default port = " +url.getDefaultPort ());
System.out.println ("File = " +url.getFile ());
System.out.println ("Host = " +url.getHost ());
System.out.println ("Path = " +url.getPath ());
System.out.println ("Port = " +url.getPort ());
System.out.println ("Protocol = " +url.getProtocol ());
System.out.println ("Query = " +url.getQuery ());
System.out.println ("Ref = " +url.getRef ());
System.out.println ("User Info = " +url.getUserInfo ());

System.out.print ('/n');

InputStream is = url.openStream ();

int ch;
while ((ch = is.read ()) != -1)
System.out.print ((char) ch);

is.close ();
}
}
  在命令行輸入java URLDemo1 http://www.javajeff.com/articles/articles/Html后,上面的代碼的輸出如下:

Authority = http://www.javajeff.com
Default port = 80
File = /articles/articles.html
Host = http://www.javajeff.com
Path = /articles/articles.html
Port = -1
Protocol = http
Query = null
Ref = null
User Info = null

<html>
<head>
<title>
Java Jeff - Articles
</title>

<meta http-equiv=Content-Type content="text/html;
charset=ISO-8859-1">
<meta name=author content="Jeff Friesen">
<meta name=keyWords content="java, virtual machine">

<script language=Javascript
if (navigator.appName == "Netscape")
document.write ("
");
</script>
</head>

<body bgcolor=#000000>
<center>
<table border=1 cellpadding=5 cellspacing=0>
<tr>
<td>
<table cellpadding=0 cellspacing=0>
<tr>
<td>
<a href=informit/informit.html>
<img alt=InformIT border=0 src=informit.gif></a>
</td>
</tr>
</table>
</td>

<td align=middle>
<img src=title.gif>


<a href=../welcome/welcome.html>
<img alt="Welcome to Java Jeff!" border=0 src=jupiter.jpg>
</a>


<img src=http://www.QQread.com/common/clear_dot.gifvspace=5>


<a href=../ads/ads.html>
<img alt="Welcome to Java Jeff!" border=0
src=jupiter.jpg>
</td>

<td>
<table cellpadding=0 cellspacing=0>
<tr>
<td>
<a href=javaworld/javaworld.html>
<img alt=JavaWorld border=0 src=javaworld.gif></a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>



<font color=#ffffff>
<center>
Best viewed at a resolution of 1024x768 or higher.


<img src=http://www.qqread.com/common/clear_dot.gifvspace=5>


<i>
Copyright © 2001-2002, Jeff Friesen. All rights
reserved.
</i>

<p>
<a href=../index.html>
<img alt=Back border=0 src=../common/back.gif></a>
</center>
</font>
</body>
</html>

  在上面的信息中,輸出標識符80是默認端口,HTTP是協議。上面給出的是輸出的HTML頁面的源代碼。

  URL的openStream()方法通常返回抽象的InputStream類的一個具體的子類所建立的對象的引用。這意味著你必須按字節次序讀取資源數據,這種做法是恰當的,因為你不知道將要讀取的數據是什么類型的。假如你事先知道要讀取的數據是文本的,并且每一行以換行符(/n)結束,你就可以按行讀取而不是按字節讀取數據了。

  下面的代碼片斷演示了把一個InputStream對象包裝進java.io.InputStreamReader對象以從8位過渡到16位字符,把結果對象包裝進java.io.BufferedReader對象以訪問BufferedReader的readLine()方法,并調用readLine()方法從資源讀取文本的所有行。

InputStream is = url.openStream ();
BufferedReader br = new BufferedReader (new InputStreamReader (is));
String line;
while ((line = br.readLine ()) != null)
System.out.println (line);
is.close ();
  有時候按字節的次序讀取數據并不方便。例如,假如資源是JPEG文件,那么獲取一個圖像處理過程并向該過程注冊一個用戶使用數據的方法更好。當圖像完整下載后立即顯示它并不困難。假如出現這種情況,你就有必要使用getContent()方法。

  當調用getContent()方法時,它會返回某種對象的Object引用,而你可以調用該對象的方法(在轉換成適當的類型后),采用更方便的方式檢索數據。但是在調用該方法前,你必須使用instanceof驗證對象的類型,防止類產生異常。

  對于JPEG資源,getContent()返回一個對象,該對象的類實現了java.awt.Image.ImageProdUCer接口。下面的代碼片斷演示了使用instanceof驗證對象是ImageProducer的,并進行了轉換。接下來可以調用ImageProducer方法注冊一個用戶并初始化圖像的使用過程。

URL url = new URL (args [0]);
Object o = url.getContent ();
if (o instanceof ImageProducer)
{
ImageProducer ip = (ImageProducer) o;
// ...
}
  技巧

  調用URL的equals(Object o)和sameFile(Object o)方法來決定兩個URL是否相同。第一個方法包含了比較的片斷,而第二個方法沒有包含。你可以參閱SDK文檔查找更多信息。

  查看一下getContent()方法的源代碼,你會找到openConnection().getContent()。此外,查看一下openStream()方法的源代碼,你會發現openConnection().getInputStream()。每個方法都首先調用URL的openConnection()方法。這個方法返回抽象的java.net.URLConnection類(描述與某些資源的連接)的一個子類建立的對象的引用。URLConnection的方法反映了資源和連接的細節信息,使我們能編寫代碼向資源寫入信息。

  列表5的URLDemo2源代碼演示了openConnection(),以及調用一些URLConnection的方法。

  列表5: URLDemo2.java

// URLDemo2.java

import java.io.*;
import java.net.*;
import java.util.*;

class URLDemo2
{
public static void main (String [] args) throws IOException
{
if (args.length != 1)
{
System.err.println ("usage: java URLDemo2 url");
return;
}

URL url = new URL (args [0]);

// 返回代表某個資源的連接的新的特定協議對象的引用

URLConnection uc = url.openConnection ();

// 進行連接

uc.connect ();

// 打印多種頭部字段的內容

Map m = uc.getHeaderFields ();
Iterator i = m.entrySet ().iterator ();

while (i.hasNext ())
System.out.println (i.next ());

// 假如資源答應輸入和輸出操作就找出來

System.out.println ("Input allowed = " +uc.getDoInput ());

System.out.println ("Output allowed = " +uc.getDoOutput ());
}
}

  在對openConnection()的調用返回后,調用了connect()方法--用于建立某種資源的連接。(盡管openConnection()方法返回一個連接對象的引用,但是openConnection()不會連接到資源)。 URLConnection的getHeaderFields()方法返回一個對象的應用,該對象的類實現了java.util.Map接口。該圖表(map)包含頭部名稱和值的集合。什么是頭部(header)?頭部是基于文本的名稱/值對,它識別資源數據的類型、數據的長度等等。

  在編譯了URLDemo2后,在命令行輸入java URLDemo2 http://www.javajeff.com,輸出如下:

Date=[Sun, 17 Feb 2002 17:49:32 GMT]
Connection=[Keep-Alive]
Content-Type=[text/html; charset=iso-8859-1]
Accept-Ranges=[bytes]
Content-Length=[7214]
null=[HTTP/1.1 200 OK]
ETag=["4470e-1c2e-3bf29d5a"]
Keep-Alive=[timeout=15, max=100]
Server=[Apache/1.3.19 (Unix) Debian/GNU]
Last-Modified=[Wed, 14 Nov 2001 16:35:38 GMT]
Input allowed = true
Output allowed = false
  上面的輸出識別了很多頭部(包括Date、null、Content-Length、 Server、Last-Modified等等)和它們的值。輸出也顯示只答應從資源讀取數據。

  你對一個程序是如何識別資源數據的是否感到驚異?仔細看一下前面的輸出,你會看到叫做Content-Type的東西。Content-Type是一個頭部,它識別了資源數據(內容)的類型是text/html。text部分就是我們所知道的類型,html部分是我們所知道的子類型。(假如內容是普通的文本,Content-Type的值可能是text/plain。上面的類型表明內容是文本的但不是沒有格式的)。Content-Type頭部是我們所知道的多用途Internet郵件擴展(MIME)的一部分。

  MIME是傳統的傳輸消息的7位ASCII標準的一種擴展。通過引入了多種頭部,MIME使視頻、聲音、圖像、不同字符集的文本與7位ASCII結合起來。有了Content-Type,MIME可以識別Content-Length和其它標準的頭部。當你使用URLConnection類的時候,你會碰到getContentType()和getContentLength()。這些方法返回的值是Content-Type和Content-Length頭部。

  你也許聽說過HTML窗體(<form>、 </form>)和其它的HTML標記。窗體使我們能夠從某種資源得到(GET)數據并按后來的處理把HTML窗體的字段數據發送(POST)到某種資源。你能夠使用URLConnection類和MIME模擬可以得到和發送數據的HTML窗體。下面說明你怎樣完成這種事務。

  假設你想把窗體數據發送(POST)到某個服務器程序。發送需要對窗體數據的操作。首先,窗體的數據必須組織為名稱/值對(name/value pair),其次每個對必須指定為name=value格式,再次假如發送多個名稱/值對,必須使用 & 符號把每對分開,最后的name內容和value的內容必須使用application/x-www-form-urlencoded MIME類型編碼。例如x=y&a=b表現了兩個名稱/值對--x/y和a/b。

  為了輔助編碼,Java提供了java.net.URLEncoder類,它聲明了一對靜態的encode()方法。每個方法有一個String參數并返回包含已編碼的參數內容的String對象的引用。例如,假如encode()發現參數中有空格,它在結果中用加號代替空格。

  下面的代碼片斷演示了調用URLEncoder的encode(String s)方法,對a 空格 b字符串進行編碼。結果a+b存儲在一個新的String對象中,result引用它。

String result = URLEncoder.encode ("a b");
  作為預備窗體數據的補充,必須告訴URLConnection對象數據已經被發送了,因為URLConnection默認的操作是獲取數據。為了完成這種事務,你可以首先把openConnection()的返回值轉換為HttpURLConnection類型(在確保該返回值的類型正確后)。接著調用結果對象的setRequestMethod(String method)方法,把POST作為method參數引用的對象的值。

  另一個必須完成的事務是調用URLConnection的setDoOutput(boolean doOutput)方法,其參數的值必須為true。這種事務是必要的,因為URLConnection對象在默認情況下不支持輸出。(接著程序最終可以調用URLConnection的getOutputStream()方法,為發送的窗體數據返回一個資源的輸出流的引用)。

  列表6是URLDemo3的源代碼,它演示了把窗體數據發送給某個"了解"application/x-www-form-urlencoded內容類型的資源。它實現了前面提到的各種事務。

  列表6: URLDemo3.java

// URLDemo3.java

import java.io.*;
import java.net.*;

class URLDemo3
{
public static void main (String [] args) throws IOException
{
// 檢查最后兩個參數和參數的數量

if (args.length < 2 args.length % 2 != 0)
{
System.err.println ("usage: java URLDemo3 name value " +
"[name value ...]");
return;
}

// 建立程序連接服務器程序資源的URL對象,它返回一個窗體的名稱/值對

URL url;
url = new URL
("http://banshee.cs.uow.edu.au:2000/~nabg/echo.cgi");

// 向某個特定協議對象返回表現http資源連接的引用

URLConnection uc = url.openConnection ();

// 驗證連接的類型,必須是HttpURLConnection的

if (!(uc instanceof HttpURLConnection))
{
System.err.println ("Wrong connection type");
return;
}

// 表明程序必須把名稱/值對輸出到服務器程序資源

uc.setDoOutput (true);

// 表明只能返回有用的信息

uc.setUseCaches (false);

//設置Content-Type頭部指示指定URL已編碼數據的窗體MIME類型

uc.setRequestProperty ("Content-Type",
"application/x-www-form-urlencoded");

// 建立名稱/值對內容發送給服務器

String content = buildContent (args);

//設置Content-Type頭部指示指定URL已編碼數據的窗體MIME類型

uc.setRequestProperty ("Content-Length",
"" + content.length ());

// 提取連接的適當的類型

HttpURLConnection hc = (HttpURLConnection) uc;

// 把HTTP請求方法設置為POST(默認的是GET)

hc.setRequestMethod ("POST");

// 輸出內容

OutputStream os = uc.getOutputStream ();
DataOutputStream dos = new DataOutputStream (os);
dos.writeBytes (content);
dos.flush ();
dos.close ();

// 從服務器程序資源輸入和顯示內容

InputStream is = uc.getInputStream ();

int ch;
while ((ch = is.read ()) != -1)
System.out.print ((char) ch);

is.close ();
}

static String buildContent (String [] args)
{
StringBuffer sb = new StringBuffer ();

for (int i = 0; i < args.length; i++)
{
// 為正確的傳輸對參數編碼

String encodedItem = URLEncoder.encode (args [i]);

sb.append (encodedItem);

if (i % 2 == 0)
sb.append ("="); // 分離名稱和值
else
sb.append ("&"); // 分離名稱/值對
}

// 刪除最后的 & 間隔符

sb.setLength (sb.length () - 1);

return sb.toString ();
}
}
  你可以會希奇為什么URLDemo3沒有調用URLConnection的connect()的方法。這個方法沒有被明顯的調用,因為假如連向資源的連接沒有建立的話,其它的URLConnection方法(例如getContentLength())會明確的調用connect()方法。但是一旦連建立了接,調用這些方法(例如setDoOutput(boolean doOutput))就是違反規定的。在connect()被(明確地或隱含地)調用后,這些方法會產生一個IllegalStateException對象。
在URLDemo3編譯后,在命令行輸入java URLDemo3 name1 value1 name2 value2 name3 value3,你可以看到下面的輸出:

<html> <head>
<title>Echoing your name value pairs</title>
</head>
<body>
<ol>
<li>name1 : value1
<li>name2 : value2
<li>name3 : value3
</ol>
<hr>
Mon Feb 18 08:58:45 2002
</body>
</html>
  該服務器程序資源的輸出由HTML組成,這些HTML回應的是name1、value1、name2、 value2、name3和value3。

  技巧

  假如你需要URL對象的URL的字符串表現形式,請調用toExternalForm()或toString()。兩種方法的功能是相同的。

  總結

  本文研究了Java的網絡API,聚焦于URI、URL和URN。你學習了這些概念,以及怎樣使用URI和URL(URL相關)的類工作,同時你學習了MIME的知識以及它與URL的關系。現在你應該編寫一些代碼熟悉一下所學的內容了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲综合在线小说| 久久久久久久久久国产精品| 亚洲最大福利视频网| 久久久av一区| 欧美精品videosex性欧美| 91免费看视频.| 成人动漫网站在线观看| 91探花福利精品国产自产在线| 欧美午夜视频在线观看| 亚洲一区二区三区777| 68精品国产免费久久久久久婷婷| 91精品久久久久久久久久久久久久| 日韩有码在线电影| 欧美午夜女人视频在线| 午夜精品免费视频| 欧美激情国产日韩精品一区18| 国产精自产拍久久久久久| 国产精品爽爽ⅴa在线观看| 欧美亚洲另类激情另类| 精品国产一区二区三区四区在线观看| 亚洲电影免费观看高清完整版| 亚洲激情视频在线| 色综合久久悠悠| 日韩小视频在线观看| 81精品国产乱码久久久久久| 国产视频福利一区| 欧美孕妇毛茸茸xxxx| 成人网在线视频| 成人免费福利视频| 91人人爽人人爽人人精88v| 国产精品久久久久久久午夜| 91av网站在线播放| 欧美日韩在线看| 一本一本久久a久久精品牛牛影视| 亚洲xxx大片| 亚洲欧美国产制服动漫| 欧美电影《睫毛膏》| 激情成人在线视频| 成人黄在线观看| 97免费视频在线| 国产视频综合在线| 色噜噜狠狠色综合网图区| 国产精品久久久久久久久粉嫩av| 欧美日韩国产精品一区| 色噜噜狠狠狠综合曰曰曰88av| 日韩hd视频在线观看| 一本大道久久加勒比香蕉| 欧美做受高潮电影o| 欧美亚洲一区在线| 久久成人免费视频| 最新亚洲国产精品| 国产欧美日韩专区发布| 在线a欧美视频| 欧美在线亚洲一区| 欧美乱大交xxxxx另类电影| 日日摸夜夜添一区| 伊人久久久久久久久久久久久| 久久久久久高潮国产精品视| 亚洲日韩第一页| 亚洲第一级黄色片| 国产精品va在线| 亚洲一区二区三区四区在线播放| 成人黄色影片在线| 4388成人网| 国产午夜精品免费一区二区三区| 久久久久久999| 日韩在线观看免费av| 亚洲男人天堂视频| 奇米影视亚洲狠狠色| 91精品国产精品| 国产精品一区二区久久| 亚洲精品欧美极品| 国产欧美中文字幕| 国产精品一区久久久| 国产噜噜噜噜久久久久久久久| 亚洲经典中文字幕| 久久久之久亚州精品露出| 色狠狠久久aa北条麻妃| 亚洲一区二区国产| 亚洲人成毛片在线播放| 精品国产31久久久久久| www日韩中文字幕在线看| 国产精品偷伦免费视频观看的| 欧美激情影音先锋| 亚洲电影中文字幕| 亚洲大胆人体视频| 日产日韩在线亚洲欧美| 欧美激情在线有限公司| 国产三级精品网站| 欧美性xxxx极品高清hd直播| 亚洲视频在线观看免费| 91精品综合久久久久久五月天| 欧美精品免费在线| 精品国产老师黑色丝袜高跟鞋| 国产精品欧美激情在线播放| 日韩欧美成人区| 欧美视频国产精品| 精品国产91乱高清在线观看| 亚洲国产精品嫩草影院久久| 麻豆国产va免费精品高清在线| 亚洲免费视频一区二区| 亚洲成成品网站| 成人久久一区二区| 色综合久久悠悠| 国产精品免费一区二区三区都可以| 2019国产精品自在线拍国产不卡| 色老头一区二区三区在线观看| 日韩中文字幕欧美| 欧美日韩一区二区在线| 亚洲一区二区三区xxx视频| 亚洲网站在线播放| 久久99精品久久久久久青青91| 92看片淫黄大片看国产片| 欧美激情啊啊啊| 亚洲欧洲日产国码av系列天堂| 久久久国产一区二区三区| 国产在线拍偷自揄拍精品| 欧美最顶级的aⅴ艳星| 美日韩在线视频| 日韩欧美在线网址| 欧美一级视频免费在线观看| 国产精品丝袜高跟| 日韩激情视频在线| 5252色成人免费视频| 日韩精品极品在线观看| 亚洲人成欧美中文字幕| 久久久精品久久久久| 亚洲福利在线播放| 国产精品99导航| 伊人成人开心激情综合网| 国产91色在线播放| 欧美激情奇米色| 久久久极品av| 欧美成人亚洲成人日韩成人| 欧美一级片久久久久久久| 久久理论片午夜琪琪电影网| 搡老女人一区二区三区视频tv| 日日狠狠久久偷偷四色综合免费| 国内成人精品视频| 国产欧美日韩免费看aⅴ视频| 91精品国产高清自在线看超| 91在线免费观看网站| 久久国产精品视频| 亚洲九九九在线观看| 日韩美女在线观看一区| 日韩中文字幕在线观看| 色综合视频一区中文字幕| 亚洲精品美女视频| 日韩免费不卡av| 91亚洲国产成人精品性色| 午夜欧美大片免费观看| 久99久在线视频| 亚洲人成在线观看网站高清| 97视频国产在线| 亚洲亚裔videos黑人hd| 国产精品视频地址| 亚洲国产欧美久久| 国产精品久久久久久久午夜| 亚洲一区二区久久久久久| 在线丨暗呦小u女国产精品| 亚洲激情在线观看视频免费| 亚洲高清福利视频| 国产精品∨欧美精品v日韩精品| 国产极品精品在线观看|