uri 和url

這兩天在寫代碼的時候,由於涉及到資源的位置,因此,需要在Java Bean中定義一些字段,用來表示資源的位置,比如:imgUrl,logoUri等等。但是,每次定義的時候,心裏都很糾結,是該用imgUrl還是imgUri呢?

同樣的,另外一個問題:String HttpServletRequest.getRequestURI();和StringBuffer HttpServletRequest.getRequestURL();返回的內容有何不同?爲什麼會如此?

帶着這些問題到網上去搜了下,沒發現讓自己看了明白的解釋,於是,想到了Java類庫裏有兩個對應的類java.net.URI和java.net.URL,終於,在這兩個類裏的javadoc裏找到了答案。

URIs, URLs, and URNs

首先,URI,是uniform resource identifier,統一資源標識符,用來唯一的標識一個資源。而URL是uniform resource locator,統一資源定位器,它是一種具體的URI,即URL可以用來標識一個資源,而且還指明瞭如何locate這個資源。而URN,uniform resource name,統一資源命名,是通過名字來標識資源,比如mailto:[email protected]。也就是說,URI是以一種抽象的,高層次概念定義統一資源標識,而URL和URN則是具體的資源標識的方式。URL和URN都是一種URI。

在Java的URI中,一個URI實例可以代表絕對的,也可以是相對的,只要它符合URI的語法規則。而URL類則不僅符合語義,還包含了定位該資源的信息,因此它不能是相對的,schema必須被指定。

ok,現在回答文章開頭提出的問題,到底是imgUrl好呢,還是imgUri好?顯然,如果說imgUri是肯定沒問題的,因爲即使它實際上是url,那它也是uri的一種。那麼用imgUrl有沒有問題呢?此時則要看它的可能取值,如果是絕對路徑,能夠定位的,那麼用imgUrl是沒問題的,而如果是相對路徑,那還是不要用ImgUrl的好。總之,用imgUri是肯定沒問題的,而用imgUrl則要視實際情況而定。

第二個,從HttpServletRequest的javadoc中可以看出,getRequestURI返回一個String,“the part of this request’s URL from the protocol name up to the query string in the first line of the HTTP request”,比如“POST /some/path.html?a=b HTTP/1.1”,則返回的值爲”/some/path.html”。現在可以明白爲什麼是getRequestURI而不是getRequestURL了,因爲此處返回的是相對的路徑。而getRequestURL返回一個StringBuffer,“The returned URL contains a protocol, server name, port number, and server path, but it does not include query string parameters.”,完整的請求資源路徑,不包括querystring。

總結一下:URL是一種具體的URI,它不僅唯一標識資源,而且還提供了定位該資源的信息。URI是一種語義上的抽象概念,可以是絕對的,也可以是相對的,而URL則必須提供足夠的信息來定位,所以,是絕對的,而通常說的relative URL,則是針對另一個absolute URL,本質上還是絕對的。

注:這裏的絕對(absolute)是指包含scheme,而相對(relative)則不包含scheme。

URI抽象結構     [scheme:]scheme-specific-part[#fragment]

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

authority爲[user-info@]host[:port]

URL的格式由下列三部分組成: 
第一部分是協議(或稱爲服務方式); 
第二部分是存有該資源的主機IP地址(有時也包括端口號); 
第三部分是主機資源的具體地址。,如目錄和文件名等。 
第一部分和第二部分之間用"://"符號隔開,第二部分和第三部分用"/"符號隔開。第一部分和第二部分是不可缺少的,第三部分有時可以省略。
URI

就Android平臺而言,URI主要分三個部分:scheme, authority and path。其中authority又分爲host和port。格式如下:
scheme://host:port/path
舉個實際的例子:
content://com.example.project:200/folder/subfolder/etc
\---------/  \---------------------------/ \---/ \--------------------------/
scheme                 host               port        path
                \--------------------------------/
                          authority   

現在大家應該知道data flag中那些屬性的含義了吧,看下data flag
<data android:host="string"
      android:mimeType="string"
      android:path="string"
      android:pathPattern="string"
      android:pathPrefix="string"
      android:port="string"
      android:scheme="string" />
但是我們在程序中一般是不直接用URI來標識CP的,是的,正如我們通常見到的用定義的常量來標識。例如standard CP中的Contacts,我們就用Contacts.People.CONTENT_URI來標識Contacts CP中People這個表。那麼要標識某個具體的人怎麼辦呢? 這就用到了ContentUris.withAppendedId() 和 Uri.withAppendedPath()。例如我們要表示content://contacts/people/20,那麼我們就可以用如下語句:
Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, 20); 或者
Uri uri = Uri.withAppendedPath(People.CONTENT_URI, "20");

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章