在计算机术语里,“URI 统一资源标识符”是个纯粹的句法结构,用于指定“标识网络资源的字符串”的各个不同部分。
URI 的格式为 [scheme:]scheme-specific-part[#fragment]
schema
命名空间scheme-specific-part
用于标识资源,由响应的命名空间来定义格式fragment
段落
绝对 URI 与 相对 URI
- 绝对 URI:各组成部分完整的 URI
- 相对 URI:各组成部分不完整,依赖于另一绝对 URI 完成解析
比如我们常见的“./dir/../alternative_file” 就是相对路径。
不透明 URI 与 分层 URI
- 不透明 URI:scheme-specific-part 不以正斜杠“/”开头
- 分层 URI:scheme-specific-part 以正斜杠“/”开头,最为常用
分层 URI 的 scheme-specific-part 格式为 [//authority][path][?query]
authority
授权机构,具体格式为[userinfo@]host[:port]
userinfo
用户信息host
主机,一般是 IP 或域名port
端口号path
路径query
查询数据
通过标识符能够定位资源的,称之为“URL 统一资源定位符”,URL 是 URI 的子集,是目前通行最广泛的 URI。通过标识符无法定位任何资源的,称之为“URN 统一资源名称”。URI 分为 URL 和 URN 两大类。
下面是一个 URN 的例子:
mailto:i@xupu.name
现在让我们看看 Java 类库里的 URI 类和 URL 类。
// 创建对象
URI uri = URI.create(urlString);
URL url = new URL(urlString);
// 互相转换
URI uri = url.toURI();
URL url = uri.toURL();
在 Java 类库中,URI 类不包含任何访问资源的方法,它唯一的作用就是解析字符串。URL 类提供了打开一个到达资源的流的方法。因此 URL 类只能作用于 Java 类库中通用、已知如何处理的“schema 模式”,例如 http、https、ftp、file、jar。
让我们看看如何使用 URI 类:
URI uri = URI.create("http://username:password@www.example.com:80/path/to/file?p1=v1&p2=v2#hash");
System.out.println(String.format("%s %s %s %s %d %s %s %s",
uri.getScheme(),
uri.getAuthority(),
uri.getUserInfo(),
uri.getHost(),
uri.getPort(),
uri.getPath(),
uri.getQuery(),
uri.getFragment()));
// http username:password username:password@www.example.com:80 www.example.com 80 /path/to/file p1=v1&p2=v2 hash
需要注意的是,URI 会自动编解码其中的字符串,如果需要获取原生值,需要使用 getRawXXX()
方法。
相对的,URL 不会自动编解码,且 URLEncoder / URLDecoder 类提供的编解码只适用于 HTML,它与 RFC2396 中定义的编码机制不同。
URI 类还提供对相对路径和绝对路径的转换、解析,请自行尝试把玩。