欢迎光临
我们一起进阶

Java网络编程(六):URL和URI

扫码或搜索:沉默王二
发送 290992
即可立即永久解锁本站全部文章

URL 是我们每天畅游在互联网世界中最最常见的东西了,对于普通用户来说,URL 就是一个字符串,比如 http://www.justdojava.com ,但是对于我们开发者而言,除了 URL,还有一个东西叫做 URI,很多人经常搞不清楚这两个概念,本文我们就从这个话题开始。

从 URN 开始

在介绍这两个东西之前,我们还得先说说另外一个东西,叫做URN,URN的全程为Uniform Resource 译作统一资源名称,URN、URL与URI的关系类似于下图:

p258

由上图可以看到,URN 和 URL 实际上是 URI 范畴之内的概念。URN 表示给每一个互联网资源取一个名字,但是互联网资源千千万万,给每一个资源取一个不重复的名字显然不太现实,因此,并不是所有的互联网资源都有 URN ,URN 就类似于一个人的身份证号码,是唯一的,但是通过这个身份证号码找不到这个人,要找到这个人我们得通过类似于下面这种地址 “中国/广东省/广州市/天河区/马场路/南国花园/8栋/1203室” ,这种能够查找到某一个资源的字符串就是 URL ,URL 全称叫做 Uniform Resource Locator ,译作统一资源定位符,表示一个资源的地点。

URL 与 URI

URI 是 Uniform Resource Identifier 的缩写,译作统一资源标识符,RFC2396 中对这三个单词做了如下定义:

Uniform

规定统一的格式可方便处理多种不同类型的资源,而不用根据上下文环境来识别资源指定的访问方式。另外,加入新增的协议方案(如 http: 或 ftp:)也更容易。

Resource

资源的定义是“可标识的任何东西”。除了文档文件、图像或服务(例如当天的天气预报)等能够区别于其他类型的,全都可作为资源。另外,资源不仅可以是单一的,也可以是多数的集合体。

Identifier

表示可标识的对象。也称为标识符。

由此可见,URI 就是由某个协议方案表示的资源的定位标识符,而协议方案就是访问资源时所采用的协议类型的名称,比如我们采用 HTTP 协议时,协议方案就是 HTTP ,我们采用 FTP 协议时,协议方案就是 FTP ,另外还有 file、mailto、telnet 等。

按照 RFC3986 的说法,一个 URI 可以被进一步归类为一个定位器(URL),一个名字(URN),或两者都是。也就是说 URI 可以是 URL ,也可以是 URN 或两者兼备,如果你关心资源的名称,那就将 URI 定义成 URN 的形式,如果你关心资源的位置,那么就将 URI 定义成 URL 的形式,URI 中包括了 URN 和 URL 。在 RFC3986 文档中还有如下一句话:

“Future specifications and related documentation should use the general term “URI” rather than the more restrictive terms “URL” and “URN””

这句话告诉我们未来应该使用更加通用的 URI 术语,而不是受限制颇多的 URL 和 URN 。

前面介绍了 URI ,接下来我们再来探讨下 URI 的格式(基于前文得出的结论,下面涉及到的地址我将都以 URI 来称呼)。

URI 的格式

对于普通用户,说 URI 他们可能有点懵,但是说 http 开头的那个字符串肯定都知道是什么了,我们常见的网址除了 http: 开头之外,也有 ftp: 开头的,也有 mailto: 开头的,分别代表不同的含义,这是因为浏览器的功能不仅仅局限于访问 web 服务器,也可以用来访问 ftp 服务器,也可以用来浏览本地文件,也可以用来发送邮件,因此浏览器需要有一个东西来判断使用哪种功能来访问相应的数据,因此有了协议,也有了各种各样不同的 URI 。如下图是一个完整的URI:

p259

这其中用户名、密码和端口号都可以省略,在浏览器拿到这样一个 URI 之后,首先会对其进行解析,比如上面这个地址,浏览器经过解析之后,知道要去获取 www.baidu.com 服务器上的 /folder/index.html 文件。不过,在实际应用中,有的时候 URI 并不是这么清晰,比如下面这个:

http://wwww.baidu.com

这种 URI 并没有直接指定要访问哪个文件,像这种没有路径的情况,就代表访问根目录下预先设置的默认文件,一般就是 /index.html, /default.html 一类的文件,在 Java 中,我们也可以在 web.xml 中来配置这个默认文件。

有的时候我们还有可能遇到下面这种地址:

http://www.baidu.com/folder/

这个 URI 以一个 / 结尾,表示 folder 是一个目录,我们要访问的是这个目录下的文件,但是又没有说明是这个目录下的哪个文件,此时依然是采用该目录下 index.html 或者 default.html 一类的文件。

有的时候,我们还可以看到下面这种 URI:

http://www.baidu.com/folder

即 folder 后面没有 / ,此时会先将 folder 当作一个资源去访问(比如一个名为 folder 的 Servlet ),如果没有名为 folder 的资源,那么浏览器会自动在 folder 后面加上一个 / ,此时地址变为 http://www.baidu.com/folder/ ,folder 是一个目录,然后就会去尝试访问 folder 目录下的 index.html 或者 default.html注意这种自动调整只在浏览器中存在,如果你的项目是一个手机 App 或者你是一个 Ajax 请求,则不会有这种调整,即没写 / 就当做具体资源来对待,如果该资源不存在,就会报 404 ,写了/ 就当目录来对待。(OkHtpp3中是这样)

有的时候我们还可能见到下面这种URI:

http://www.baidu.com/

这个和我们介绍的第一种情况很类似,只是后面多了一个 / ,这个 / 表示我们要访问的是根目录,但是没有指定根目录下的文件,默认就是根目录下的 index.html 或者 default.html

OK,经过上面的介绍,小伙伴对 URI 最后面的 **/** 已经有了清晰的认识了吧?这个东西不可以随意省略,有 / 和没有 / ,访问结果有可能是天壤之别。

赞(0) 打赏
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

小白学堂,学的不止是技术,更是前程

关于我们免责声明

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏