URL和URI

URL和URI

URL和URLConnection类封装了大量复杂的实现细节,这些细节涉及如何从远程站点获取信息,如,可以通过传递字符串来构建一个URL对象:

1
URL url=new URL(urlString);

如果只是想获得该资源的内容,可以使用URL类中的openStream方法。该方法返回一个InputStream对象,然后就可以按照一般的用法来使用这个对象了,比如用它构建一个Scanner对象:

1
2
InputStream inStream=url.openStream();
Scanner in=new Scanner(inStream);

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
2
http://maps.yahoo.com/py/maps.py?csz=Cupertino+CA
ftp://username:password@ftp.youserver.com/pub/file.txt

URI规范给出了标记这些标识符的规则。一个URI具有以下句法:

1
[scheme:]schemeSpecificPart[#fragment]

上式中,[…]表示可选部分,他:与#可以被包含在标识符内。

包含scheme:部分的URI被称为绝对URI。否则,被称为相对URI。

如果绝对URI的schemeSpecificPart不以/开头,我们就称它是不透明的。如

1
mailto:cay@horstmann.com

所有绝对的透明URI和所有相对URI都是分层的。例如

1
2
http://java.sun.com/index.html
../../java/net/Socket.html#Socket()

一个分层URI的schemeSpecificPart具有以下结构:

1
[//authority][path][?query]

[..]表示可选

对于那些基于服务器的URI,authority部分采用以下形式

1
[user-info@]host[:part]//part必须是个整数

URI类的作用之一是解析标识符并将它分解成各种不同的组成部分。你可以用以下方法读取它们

1
2
3
4
5
6
7
8
9
getScheme
getSchemeSpecificPart
getAuthority
getUserInfo
getHost
getPost
getPath
getQuery
getFragment

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
2
relative=base.relativize(combined);
combined=base.resolve(relative);
Donate comment here