url和uri区别

url和uri区别
这两天在写代码的时候,由于涉及到资源的位置,因此,需要在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为[[email protected]]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对象不适用。

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
mntkiCeaiNYNBGc/ku4YGg==