URL和URI
URL和URLConnection类封装了大量复杂的实现细节,这些细节涉及如何从远程站点获取信息,如,可以通过传递字符串来构建一个URL对象:
1 | URL url=new URL(urlString); |
如果只是想获得该资源的内容,可以使用URL类中的openStream方法。该方法返回一个InputStream对象,然后就可以按照一般的用法来使用这个对象了,比如用它构建一个Scanner对象:
1 | InputStream inStream=url.openStream(); |
java.net包对统一资源定位符(URL)和统一资源标识符(URI)做了非常有用的区分。
URI纯粹是个句法结构,用于指定标识Web资源的字符串的各个不同部分,URL是个URI的一个特例,它包含了用于定位Web资源的足够信息。其他URI,比如
1 | mailto:cay@horstmann.com |
则不属于定位符,因为根据该标识符我们无法定位任何数据,像这样的URI我们称之为URN(统一资源名称)
在java类库中,URI类不包含任何用于访问资源的方法,它唯一的作用就是解析。相反的是,URL类可以打开一个到达资源的流,因此,URL类只能作用于那些java类库知道该如何处理的模式,例如http:、https:、ftp:、本地文件系统(file:)和jar文件(jar:)
对URI进行解析并不是可有可无的,因为它有时候会变得非常复杂。例如,
1 | http://maps.yahoo.com/py/maps.py?csz=Cupertino+CA |
URI规范给出了标记这些标识符的规则。一个URI具有以下句法:
1 | [scheme:]schemeSpecificPart[#fragment] |
上式中,[…]表示可选部分,他:与#可以被包含在标识符内。
包含scheme:部分的URI被称为绝对URI。否则,被称为相对URI。
如果绝对URI的schemeSpecificPart不以/开头,我们就称它是不透明的。如
1 | mailto:cay@horstmann.com |
所有绝对的透明URI和所有相对URI都是分层的。例如
1 | http://java.sun.com/index.html |
一个分层URI的schemeSpecificPart具有以下结构:
1 | [//authority][path][?query] |
[..]表示可选
对于那些基于服务器的URI,authority部分采用以下形式
1 | [user-info@]host[:part]//part必须是个整数 |
URI类的作用之一是解析标识符并将它分解成各种不同的组成部分。你可以用以下方法读取它们
1 | getScheme |
URI类的另一个作用是处理绝对标识符和相对标识符。如果存在一个如下的绝对URI:
1 | http://docs.mycompany.com/api/java/net/ServerSocket.html |
和一个如下的相对URI
1 | ../../java/net/Socket.html#Socket() |
那么可以将它们合并成一个绝对URI
1 | http://docs.mycompany.com/api/java/net/Socket.html#Socket() |
这个过程被称为相对URL的转化,与此相反的过程称之为相对化。例如,假设有一个基本URI
1 | http://docs.mycompany.com/api |
和另一个URI
1 | http://docs.mycompany.com/api/java/lang/String.html |
那么相对化之后的URI就是
1 | java/lang/String.html |
URI类同时支持以下两个操作
1 | relative=base.relativize(combined); |