這兩天在寫代碼的時候,因爲涉及到資源的位置,所以,須要在Java Bean中定義一些字段,用來表示資源的位置,好比:imgUrl,logoUri等等。可是,每次定義的時候,內心都很糾結,是該用imgUrl仍是imgUri呢?html
一樣的,另一個問題:String HttpServletRequest.getRequestURI();和StringBuffer HttpServletRequest.getRequestURL();返回的內容有何不一樣?爲何會如此?java
帶着這些問題到網上去搜了下,沒發現讓本身看了明白的解釋,因而,想到了Java類庫裏有兩個對應的類java.net.URI和java.net.URL,終於,在這兩個類裏的javadoc裏找到了答案。api
首先,URI,是uniform resource identifier,統一資源標識符,用來惟一的標識一個資源。而URL是uniform resource locator,統一資源定位器,它是一種具體的URI,即URL能夠用來標識一個資源,並且還指明瞭如何locate這個資源。而 URN,uniform resource name,統一資源命名,是經過名字來標識資源,好比mailto:java-net@java.sun.com。也就是說,URI是以一種抽象的,高層 次概念定義統一資源標識,而URL和URN則是具體的資源標識的方式。URL和URN都是一種URI。oracle
在Java的URI中,一個URI實例能夠表明絕對的,也能夠是相對的,只要它符合URI的語法規則。而URL類則不只符合語義,還包含了定位該資源的信息,所以它不能是相對的,schema必須被指定。ide
ok,如今回答文章開頭提出的問題,究竟是imgUrl好呢,仍是imgUri好?顯然,若是說imgUri是確定沒問題的,由於即便它其實是 url,那它也是uri的一種。那麼用imgUrl有沒有問題呢?此時則要看它的可能取值,若是是絕對路徑,可以定位的,那麼用imgUrl是沒問題的, 而若是是相對路徑,那仍是不要用ImgUrl的好。總之,用imgUri是確定沒問題的,而用imgUrl則要視實際狀況而定。this
第二個,從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
總結一下:URL是一種具體的URI,它不只惟一標識資源,並且還提供了定位該資源的信息。URI是一種語義上的抽象概念,能夠是絕對的,也能夠是 相對的,而URL則必須提供足夠的信息來定位,因此,是絕對的,而一般說的relative URL,則是針對另外一個absolute URL,本質上仍是絕對的。spa
注:這裏的絕對(absolute)是指包含scheme,而相對(relative)則不包含scheme。.net
URI抽象結構 [scheme:]scheme-specific-part[#fragment]code
[scheme:][//authority][path][?query][#fragment]
authority爲[user-info@]host[:port]
參考資料:
http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html
http://en.wikipedia.org/wiki/Uniform_Resource_Identifier
http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html
ps:
java.net.URL類不提供對標準RFC2396規定的特殊字符的轉義,所以須要調用者本身對URL各組成部分進行encode。而 java.net.URI則會提供轉義功能。所以The recommended way to manage the encoding and decoding of URLs is to use java.net.URI. 可使用URI.toURL()和URL.toURI()方法來對兩個類型的對象互相轉換。對於HTML FORM的url encode/decode可使用java.net.URLEncoder和java.net.URLDecoder來完成,可是對URL對象不適用。