<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 134,comments - 22,trackbacks - 0

    JavaURI,URLURN的使用

    從天極網(wǎng)抄錄整理 2006-1-13

    URIURLURN是識(shí)別、定位和命名網(wǎng)上資源的標(biāo)準(zhǔn)途徑。本文分析了URIURLURN的概念,以及JavaURIURL類(lèi)(以及與URL相關(guān)的類(lèi)),并演示了如何在程序中使用這些類(lèi)。

    Internet
    被認(rèn)為是全球的實(shí)際和抽象的資源的集合。實(shí)際的資源包括從文件(file)到人(person),抽象的資源包括數(shù)據(jù)庫(kù)查詢等。因?yàn)橐ㄟ^(guò)多樣的方式識(shí)別資源,所以需要標(biāo)準(zhǔn)的識(shí)別Internet資源的途徑。為了滿足這種需要,引入了URIURLURN

    URIURLURN的概念
    URI

    URI = Uniform Resource Identifier

    There are two types of URIs: URLs and URNs.

    See RFC 1630: Universal Resource Identifiers in WWW: A Unifying Syntax for the Expression of Names and Addresses of Objects on the Network as used in the WWW.

    URL

    URL = Uniform Resource Locator

    See RFC 1738: Uniform Resource Locators (URL)

    URN

    URN = Uniform Resource Name.


    URI
    URLURN是彼此關(guān)聯(lián)的。URI位于頂層,URLURN的范疇位于底層。URLURN都是URI的子范疇。

    URI
    翻譯為統(tǒng)一資源標(biāo)識(shí),它是以某種標(biāo)準(zhǔn)化的方式標(biāo)識(shí)資源的字符串。這種字符串以scheme開(kāi)頭,語(yǔ)法如下:

    [scheme:] scheme-specific-part

    URI
    scheme和冒號(hào)開(kāi)頭。冒號(hào)把schemescheme-specific-part分開(kāi),并且scheme-specific-part的語(yǔ)法由URIscheme決定。例如http://www.cnn.com,其中httpscheme//www.cnn.com scheme-specific-part

    URI分為絕對(duì)(absolute)或相對(duì)(relative)兩類(lèi)。絕對(duì)URI指以scheme(后面跟著冒號(hào))開(kāi)頭的URI。前面提到的http://www.cnn.com就是絕對(duì)的URI的一個(gè)例子,其它的例子還有mailto:jeff@javajeff.comnews:comp.lang.java.helpxyz://whatever。可以把絕對(duì)URI看作是以某種方式引用某種資源,而對(duì)環(huán)境沒(méi)有依賴(lài)。如果使用文件系統(tǒng)作類(lèi)比,絕對(duì)URI類(lèi)似于從根目錄開(kāi)始的某個(gè)文件的路徑。相對(duì)URI不以scheme開(kāi)始,一個(gè)例子是articles/articles.html。可以把相對(duì)URI看作是以某種方式引用某種資源,而這種方式依賴(lài)于標(biāo)識(shí)符出現(xiàn)的環(huán)境。如果用文件系統(tǒng)作類(lèi)比,相對(duì)URI類(lèi)似于從當(dāng)前目錄開(kāi)始的文件路徑。

    URI可以進(jìn)一步分為不透明的(opaque)和分層(hierarchical)的兩類(lèi)。不透明的URIscheme-specific-part不是以‘/’開(kāi)頭的絕對(duì)的URI。其例子有news:comp.lang.java和前面的mailto:jeff@javajeff.com。不透明的URI不能做進(jìn)一步的解析,不需要驗(yàn)證scheme-specific-part的有效性。與它不同的是,分層的URI是以‘/’開(kāi)頭的絕對(duì)的URI或相對(duì)的URL。分層的URIscheme-specific-part必須被分解為幾個(gè)組成部分。分層的URIscheme-specific-part必須符合下面的語(yǔ)法:

    [//authority] [path] [?query] [#fragment]

    可選的授權(quán)機(jī)構(gòu)(authority)標(biāo)識(shí)了該URI名字空間的命名機(jī)構(gòu)。如果有這一部分則以‘//’開(kāi)始。它可以是基于服務(wù)器或基于授權(quán)機(jī)構(gòu)的。基于授權(quán)機(jī)構(gòu)有特定的語(yǔ)法(本文沒(méi)有討論,因?yàn)楹苌偈褂盟诜?wù)器的語(yǔ)法如下:

    [userinfo@] host [:port]

    基于服務(wù)器的authority以用戶信息(例如用戶名)開(kāi)始,后面跟著一個(gè)@符號(hào),緊接著是主機(jī)的名稱(chēng),以及冒號(hào)和端口號(hào)。例如jeff@x.com:90就是一個(gè)基于服務(wù)器的authority,其中jeff為用戶信息,x.com為主機(jī),90為端口。

    可選的path根據(jù)authority(如果提供了)或schema(如果沒(méi)有authority)定義資源的位置。路徑(path)可以分成一系列的路徑片斷(path segment),每個(gè)路徑片斷使用‘/’與其它片斷隔開(kāi)。如果第一個(gè)路徑片斷以‘/’開(kāi)始,該路徑就被認(rèn)為是絕對(duì)的,否則路徑就被認(rèn)為是相對(duì)的。例如,/a/b/c由三個(gè)路徑片斷abc組成,此外這個(gè)路徑是絕對(duì)的,因?yàn)榈谝粋€(gè)路徑片斷(a)的前綴是‘/’。

    可選的query定義要傳遞給資源的查詢信息。資源使用該信息獲取或生成其它的的數(shù)據(jù)傳遞回調(diào)用者。例如,http://www.somesite.net/a?x=y, x=y就是一個(gè)query,在這個(gè)查詢中x是某種實(shí)體的名稱(chēng),y是該實(shí)體的值。

    最后一個(gè)部分是fragment。當(dāng)使用URI進(jìn)行某種檢索操作時(shí),后面執(zhí)行操作的軟件使用fragment聚焦于軟件感興趣的資源部分。

    分析一個(gè)例子ftp://george@x.com:90/public/notes?text=shakespeare#hamlet

    上面的URIftp識(shí)別為schema,把george@x.com:90識(shí)別為基于服務(wù)器的authority(其中george是用戶信息,x.com是主機(jī),90是端口),把/public/notes識(shí)別為路徑,把text=shakespeare識(shí)別為查詢,把hamlet識(shí)別為片斷。本質(zhì)上它是一個(gè)叫做george的用戶希望通過(guò)/public/notes路徑在服務(wù)器x.com90端口上檢索shakespeare文本的hamlet信息。

    URI的標(biāo)準(zhǔn)化(normalize


    標(biāo)準(zhǔn)化可以通過(guò)目錄術(shù)語(yǔ)來(lái)理解。假定目錄
    x直接位于根目錄之下,x有子目錄abb有文件memo.txta是當(dāng)前目錄。為了顯示memo.txt中的內(nèi)容,你可能輸入type "x"."b"memo.txt。你也可能輸入type "x"a".."b"memo.txt,在這種情況下,a..的出現(xiàn)是沒(méi)有必要的。這兩種形式都不是最簡(jiǎn)單的。但是如果輸入"x"b"memo.txt,你就指定了最簡(jiǎn)單的路徑了,從根目錄開(kāi)始訪問(wèn)memo.txt。最簡(jiǎn)單的"x"b"memo.txt路徑就是標(biāo)準(zhǔn)化的路徑。

    通常通過(guò)base + relative URI訪問(wèn)資源。Base URI是絕對(duì)URI,而Relative URI標(biāo)識(shí)了與Base URI相對(duì)的資源。因此有必要把兩種URI通過(guò)解析過(guò)程合并,相反地從合并的URI中提取Relative URI也是可行的。

    假定把x://a/作為Base URI,并把b/c作為Relative URIResolve這個(gè)相對(duì)URI將產(chǎn)生x://a/b/c。根據(jù)x://a/相對(duì)化(Relativex://a/b/c將產(chǎn)生b/c

    URI
    不能讀取/寫(xiě)入資源,這是統(tǒng)一的資源定位器(URL)的任務(wù)。URL是一種URI,它的schema是已知的網(wǎng)絡(luò)協(xié)議,并且它把URI與某種協(xié)議處理程序聯(lián)系起來(lái)(一種與資源通訊的讀/寫(xiě)機(jī)制)。

    URI
    一般不能為資源提供持久不變的名稱(chēng)。這是統(tǒng)一的資源命名(URN)的任務(wù)。URN也是一種URI,但是全球唯一的、持久不便的,即使資源不再存在或不再使用。

    使用URI

    Java
    API通過(guò)提供URI類(lèi)(位于java.net包中),使我們?cè)诖a中使用URI成為可能。URI的構(gòu)造函數(shù)建立URI對(duì)象,并且分析URI字符串,提取URI組件。URI的方法提供了如下功能:1)決定URI對(duì)象的URI是絕對(duì)的還是相對(duì)的;2)決定URI對(duì)象是opaque還是hierarchical3)比較兩個(gè)URI對(duì)象;4)標(biāo)準(zhǔn)化(normalizeURI對(duì)象;5)根據(jù)Base URI解析某個(gè)Relative URI6)根據(jù)Base URI計(jì)算某個(gè)URI的相對(duì)URI7)把URI對(duì)象轉(zhuǎn)換為URL對(duì)象。

    URI里面有多個(gè)構(gòu)造函數(shù),最簡(jiǎn)單的是URI(String uri)。這個(gè)構(gòu)造函數(shù)把String類(lèi)型的參數(shù)URI分解為組件,并把這些組件存儲(chǔ)在新的URI對(duì)象中。如果String對(duì)象的URI違反了RFC 2396的語(yǔ)法規(guī)則,將會(huì)產(chǎn)生一個(gè)java.net.URISyntaxException

    下面的代碼演示了使用URI(String uri)建立URI對(duì)象:

    URI uri = new URI ("http://www.cnn.com");


    如果知道URI是有效的,不會(huì)產(chǎn)生URISyntaxException,可以使用靜態(tài)的create(String uri)方法。這個(gè)方法分解uri,如果沒(méi)有違反語(yǔ)法規(guī)則就建立URI對(duì)象,否則將捕捉到一個(gè)內(nèi)部URISyntaxException,并把該對(duì)象包裝在一個(gè)IllegalArgumentException中拋出。

    下面的代碼片斷演示了create(String uri)

    URI uri = URI.create ("http://www.cnn.com");


    URI構(gòu)造函數(shù)和create(String uri)方法試圖分解出URIauthority的用戶信息、主機(jī)和端口部分。對(duì)于正確形式的字符串會(huì)成功,對(duì)于錯(cuò)誤形式的字符串,他們將會(huì)失敗。如果想確認(rèn)某個(gè)URIauthority是基于服務(wù)器的,并且分解出用戶信息、主機(jī)和端口,這時(shí)候可以調(diào)用URIparseServerAuthority()方法。如果成功分解出URI,該方法將返回包含用戶信息、主機(jī)和端口部分的新URI對(duì)象,否則該方法將產(chǎn)生一個(gè)URISyntaxException

    下面的代碼片斷演示了parseServerAuthority()

    // 下面的parseServerAuthority()調(diào)用出現(xiàn)后會(huì)發(fā)生什么情況?
    URI uri = new URI ("http://foo:bar").parseServerAuthority();

    一旦擁有了URI對(duì)象,你就可以通過(guò)調(diào)用getAuthority()getFragment()getHost()getPath()getPort()getQuery()getScheme()getSchemeSpecificPart() getUserInfo()方法提取信息。以及isAbsolute()isOpaque()等方法。

    程序1: URIDemo1.java

    import java.net.*;

    public class URIDemo1 {
     public static void main (String [] args) throws Exception {
        if (args.length != 1) {
          System.err.println ("usage: java URIDemo1 uri");
          return;
        }
        URI uri = new URI (args [0]);

        System.out.println ("Authority = " +uri.getAuthority ());
        System.out.println ("Fragment = " +uri.getFragment ());
        System.out.println ("Host = " +uri.getHost ());
        System.out.println ("Path = " +uri.getPath ());
        System.out.println ("Port = " +uri.getPort ());
        System.out.println ("Query = " +uri.getQuery ());
        System.out.println ("Scheme = " +uri.getScheme ());
        System.out.println ("Scheme-specific part = " + uri.getSchemeSpecificPart ());
        System.out.println ("User Info = " +uri.getUserInfo ());
        System.out.println ("URI is absolute: " +uri.isAbsolute ());
        System.out.println ("URI is opaque: " +uri.isOpaque ());
     }
    }


    輸入java URIDemo1命令后,輸出結(jié)果如下:

    query://jeff@books.com:9000/public/manuals/appliances?stove#ge
    Authority = jeff@books.com:9000
    Fragment = ge
    Host = books.com
    Path = /public/manuals/appliances
    Port = 9000
    Query = stove
    Scheme = query
    Scheme-specific part = //jeff@books.com:9000/public/manuals/appliances?stove
    User Info = jeff
    URI is absolute: true
    URI is opaque: false



    URI類(lèi)支持基本的操作,包括標(biāo)準(zhǔn)化(normalize)、分解(resolution)和相對(duì)化(relativize)。下例演示了normalize()方法。


    程序2: URIDemo2.java

    import java.net.*;

    class URIDemo2 {
     public static void main (String [] args) throws Exception {
        if (args.length != 1) {
          System.err.println ("usage: java URIDemo2 uri");
          return;
        }
        URI uri = new URI (args [0]);
        System.out.println ("Normalized URI = " + uri.normalize());
     }
    }


    在命令行輸入java URIDemo2 x/y/../z/./q,將看到下面的輸出:
    Normalized URI = x/z/q

    上面的輸出顯示y...消失了。

    URI通過(guò)提供resolve(String uri)resolve(URI uri)relativize(URI uri)方法支持反向解析和相對(duì)化操作。如果指定的URI違反了RFC 2396語(yǔ)法規(guī)則,resolve(String uri)通過(guò)的內(nèi)部的create(String uri)調(diào)用間接地產(chǎn)生一個(gè)IllegalArgumentException下面的代碼演示了resolve(String uri)relativize(URI uri)

    程序3: URIDemo3.java

    import java.net.*;

    class URIDemo3 {
     public static void main (String [] args) throws Exception {
        if (args.length != 2) {
          System.err.println ("usage: " + "java URIDemo3 uriBase uriRelative");
          return;
        }

        URI uriBase = new URI (args [0]);
        System.out.println ("Base URI = " +uriBase);

        URI uriRelative = new URI (args [1]);
        System.out.println ("Relative URI = " +uriRelative);

        URI uriResolved = uriBase.resolve (uriRelative);
        System.out.println ("Resolved URI = " +uriResolved);

        URI uriRelativized = uriBase.relativize (uriResolved);
        System.out.println ("Relativized URI = " +uriRelativized);
     }
    }


    編譯URIDemo3后,在命令行輸入java URIDemo3 http://www.somedomain.com/ x/../y,輸出如下:

    Base URI = http://www.somedomain.com/
    Relative URI = x/../y
    Resolved URI = http://www.somedomain.com/y
    Relativized URI = y



    使用URL

    Java
    提供了URL類(lèi),每一個(gè)URL對(duì)象都封裝了資源標(biāo)識(shí)符和協(xié)議處理程序。獲得URL對(duì)象的途徑之一是調(diào)用URItoURL()方法,也可以直接調(diào)用URL的構(gòu)造函數(shù)來(lái)建立URL對(duì)象。


    URL類(lèi)有多個(gè)構(gòu)造函數(shù)。其中最簡(jiǎn)單的是URL(String url),它有一個(gè)String類(lèi)型的參數(shù)。如果某個(gè)URL沒(méi)有包含協(xié)議處理程序或該URL的協(xié)議是未知的,其它的構(gòu)造函數(shù)會(huì)產(chǎn)生一個(gè)java.net.MalformedURLException
    下面的代碼片斷演示了使用URL(String url)建立一個(gè)URL對(duì)象,該對(duì)象封裝了一個(gè)簡(jiǎn)單的URL組件和http協(xié)議處理程序。

    URL url = new URL ("http://www.informit.com");


    一旦擁有了URL對(duì)象,就可以使用getAuthority()getDefaultPort() getFile() getHost() getPath()getPort() getProtocol()getQuery()getRef()getUserInfo()getDefaultPort()等方法提取各種組件。如果URL中沒(méi)有指定端口,getDefaultPort()方法返回URL對(duì)象的協(xié)議默認(rèn)端口。getFile()方法返回路徑和查詢組件的結(jié)合體。getProtocol()方法返回資源的連接類(lèi)型(例如httpmailtoftp)。getRef()方法返回URL的片斷。最后,getUserInfo()方法返回Authority的用戶信息部分。還可以調(diào)用openStream()方法得到java.io.InputStream引用。使用這種引用,可以用面向字節(jié)的方式讀取資源。

    下面是URLDemo1的代碼。該程序建立一個(gè)URL對(duì)象,調(diào)用URL的各種方法來(lái)檢索該URL的信息,調(diào)用URLopenStream()方法打開(kāi)與資源的連接并讀取/打印這些字節(jié)。

    程序4: 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>

    </html>



    URLopenStream()方法返回的InputStream類(lèi)型,這意味著你必須按字節(jié)次序讀取資源數(shù)據(jù),這種做法是恰當(dāng)?shù)模驗(yàn)槟悴恢缹⒁x取的數(shù)據(jù)是什么類(lèi)型。如果你事先知道要讀取的數(shù)據(jù)是文本,并且每一行以換行符("n)結(jié)束,你就可以按行讀取而不是按字節(jié)讀取數(shù)據(jù)了。

    下面的代碼片斷演示了把一個(gè)InputStream對(duì)象包裝進(jìn)InputStreamReader以從8位過(guò)渡到16位字符,進(jìn)而把結(jié)果對(duì)象包裝進(jìn)BufferedReader以調(diào)用其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 ();


    有時(shí)候按字節(jié)的次序讀取數(shù)據(jù)并不方便。例如,如果資源是JPEG文件,那么獲取一個(gè)圖像處理過(guò)程并向該過(guò)程注冊(cè)一個(gè)用戶使用數(shù)據(jù)的方法更好。如果出現(xiàn)這種情況,你就有必要使用getContent()方法。

    當(dāng)調(diào)用getContent()方法時(shí),它會(huì)返回某種對(duì)象的引用,而你可以調(diào)用該對(duì)象的方法(在轉(zhuǎn)換成適當(dāng)?shù)念?lèi)型后),采用更方便的方式取得數(shù)據(jù)。但是在調(diào)用該方法前,最好使用instanceof驗(yàn)證對(duì)象的類(lèi)型,防止類(lèi)產(chǎn)生異常。

    對(duì)于JPEG資源,getContent()返回一個(gè)對(duì)象,該對(duì)象實(shí)現(xiàn)了java.awt.Image.ImageProducer接口。下面的代碼演示了使用如何getContent()

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



    查看一下getContent()方法的源代碼,你會(huì)找到openConnection().getContent()URLopenConnection()方法返回一個(gè)java.net.URLConnection對(duì)象。URLConnection的方法反映了資源和連接的細(xì)節(jié)信息,使我們能編寫(xiě)代碼訪問(wèn)資源。

    下面URLDemo2代碼演示了openConnection(),以及如何調(diào)用URLConnection的方法。

    程序5: 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]);

        //
    返回代表某個(gè)資源的連接的新的特定協(xié)議對(duì)象的引用
        URLConnection uc = url.openConnection ();

        //
    進(jìn)行連接
        uc.connect ();

        //
    打印header的內(nèi)容
        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 ());
     }
    }

    URLConnectiongetHeaderFields()方法返回一個(gè)java.util.Map。該map包含header名稱(chēng)和值的集合。header是基于文本的名稱(chēng)/值對(duì),它識(shí)別資源數(shù)據(jù)的類(lèi)型、數(shù)據(jù)的長(zhǎng)度等等。

    編譯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



    仔細(xì)看一下前面的輸出,會(huì)看到叫做Content-Type的東西。Content-Type識(shí)別了資源數(shù)據(jù)的類(lèi)型是text/htmltext部分叫做類(lèi)型,html部分叫做子類(lèi)型。如果內(nèi)容是普通的文本,Content-Type的值可能是text/plaintext/html表明內(nèi)容是文本的但是html格式的。

    Content-Type是多用途Internet郵件擴(kuò)展(MIME)的一部分。MIME是傳統(tǒng)的傳輸消息的7ASCII標(biāo)準(zhǔn)的一種擴(kuò)展。通過(guò)引入了多種headerMIME使視頻、聲音、圖像、不同字符集的文本與7ASCII結(jié)合起來(lái)。當(dāng)使用URLConnection類(lèi)的時(shí)候,你會(huì)遇到getContentType()getContentLength()。這些方法返回的值是Content-TypeContent-Length的信息。

    使用URL提交HTTP請(qǐng)求


    你也許聽(tīng)說(shuō)過(guò)
    HTML<form>。它使我們能夠從某種資源得到(GET)數(shù)據(jù)并按后來(lái)的處理把<form>的字段數(shù)據(jù)發(fā)送(POST)到某種資源。


    假設(shè)你想把<form>數(shù)據(jù)發(fā)送(POST)到某個(gè)服務(wù)器程序。首先,<form>的數(shù)據(jù)必須組織為名稱(chēng)/值對(duì)(name/value pair),其次每個(gè)對(duì)必須指定為name=value格式,再次如果發(fā)送多個(gè)名稱(chēng)/值對(duì),必須使用 & 符號(hào)把每對(duì)分開(kāi)。最后name內(nèi)容和value的內(nèi)容必須使用application/x-www-form-urlencoded MIME類(lèi)型編碼。

    為了輔助編碼,Java提供了java.net.URLEncoder類(lèi),它聲明了一對(duì)靜態(tài)的encode()方法。每個(gè)方法有一個(gè)String參數(shù)并返回包含已編碼的內(nèi)容。例如,如果encode()發(fā)現(xiàn)參數(shù)中有空格,它在結(jié)果中用加號(hào)代替空格。

    下面的代碼演示了調(diào)用URLEncoderencode(String s)方法,對(duì)‘a空格b’進(jìn)行編碼。結(jié)果a+b存儲(chǔ)在一個(gè)新的String對(duì)象中。

    String result = URLEncoder.encode ("a b");



    另一個(gè)必須完成的事務(wù)是調(diào)用URLConnectionsetDoOutput(boolean doOutput)方法,其參數(shù)的值必須為true。這種事務(wù)是必要的,因?yàn)?/span>URLConnection對(duì)象在默認(rèn)情況下不支持輸出。下面是URLDemo3的源代碼,它演示了把窗體數(shù)據(jù)發(fā)送給某個(gè)資源。它實(shí)現(xiàn)了前面提到的各種事務(wù)。

    程序6: 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 = new URL("http://banshee.cs.uow.edu.au:2000/~nabg/echo.cgi");
        URLConnection uc = url.openConnection ();

        //
    驗(yàn)證連接的類(lèi)型,必須是HttpURLConnection
        if (!(uc instanceof HttpURLConnection)) {
          System.err.println ("Wrong connection type");
          return;
        }

        //
    必須能把名/值對(duì)輸出到服務(wù)器程序資源
        uc.setDoOutput (true);

        //
    不使用cache
        uc.setUseCaches (false);

        //
    設(shè)置Content-Type指示指定MIME類(lèi)型
        uc.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded");

        //
    建立名/值對(duì)內(nèi)容發(fā)送給服務(wù)器
        String content = buildContent (args);

        //
    設(shè)置Content-Length
        uc.setRequestProperty ("Content-Length", "" + content.length ());

        //
    連接的適當(dāng)類(lèi)型
        HttpURLConnection hc = (HttpURLConnection) uc;

        //
    HTTP請(qǐng)求方法設(shè)置為POST(默認(rèn)的是GET
        hc.setRequestMethod ("POST");

        //
    輸出內(nèi)容
        OutputStream os = uc.getOutputStream ();
        DataOutputStream dos = new DataOutputStream (os);
        dos.writeBytes (content);
        dos.flush ();
        dos.close ();

        //
    從服務(wù)器程序資源輸入和顯示內(nèi)容
        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++) {
         //
    對(duì)參數(shù)編碼
          String encodedItem = URLEncoder.encode (args [i]);
          sb.append (encodedItem);
     
         if (i % 2 == 0)
           sb.append ("="); //
    分離名稱(chēng)和值
         else
           sb.append ("&"); //
    分離名稱(chēng)/值對(duì)
       } // end for

       //
    刪除最后的 & 間隔符
       sb.setLength (sb.length () - 1);
       return sb.toString ();
     }
    }

    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>



    總結(jié)

    本文研究了Java的網(wǎng)絡(luò)API,聚焦于URIURL。你學(xué)習(xí)了這些概念,以及怎樣使用URIURLURL相關(guān)),同時(shí)你學(xué)習(xí)了MIME的知識(shí)以及它與URL的關(guān)系。

    posted on 2008-10-04 11:54 何克勤 閱讀(2008) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): J2SE
    主站蜘蛛池模板: 亚洲AV无码乱码在线观看裸奔| 亚洲三级在线观看| 亚洲最大无码中文字幕| 乱人伦中文视频在线观看免费| 一个人免费日韩不卡视频| 日韩电影免费在线| 久久亚洲国产精品| 亚洲av成人片在线观看| 亚洲视频免费在线观看| 免费a在线观看播放| 亚洲另类古典武侠| 久久久精品国产亚洲成人满18免费网站 | 免费a级毛片无码a∨免费软件| 西西大胆无码视频免费| 亚洲日韩精品无码专区网址| 亚洲色大网站WWW永久网站| 日本一道本不卡免费| 全部免费毛片免费播放| 亚洲喷奶水中文字幕电影| 中文在线免费观看| 在线观看亚洲免费视频| 亚洲成人免费网址| 免费国产污网站在线观看| 一本色道久久88综合亚洲精品高清| 亚洲毛片基地日韩毛片基地| 二个人看的www免费视频| 日本一道一区二区免费看| 亚洲综合小说久久另类区| 久青草视频在线观看免费| 在线观看亚洲免费| 亚洲国产日韩综合久久精品| 无码A级毛片免费视频内谢| 国产亚洲色视频在线| 看免费毛片天天看| 成人a视频片在线观看免费| 久久亚洲AV无码精品色午夜 | 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 永久免费av无码入口国语片| 波多野结衣一区二区免费视频| 亚洲日本va在线观看| 91成人免费观看|