阅读(3002) (6)

鸿蒙OS URI

2022-06-06 16:32:29 更新

URI

java.lang.Object

|---java.net.URI

public final class URI
extends Object
implements Comparable<URI>, Serializable

表示统一资源标识符 (URI) 引用。

除了下面提到的一些小偏差之外,此类的一个实例表示由 RFC 2396 定义的 URI 引用:统一资源标识符 (URI):通用语法,由 RFC 2732 修订:URL 中文字 IPv6 地址的格式。 Literal IPv6 地址格式也支持 scope_ids。 此处描述了 scope_ids 的语法和用法。 此类提供了用于从其组件或通过解析其字符串形式创建 URI 实例的构造函数、用于访问实例的各种组件的方法,以及用于规范化、解析和相对化 URI 实例的方法。 此类的实例是不可变的。

URI 语法和组件 在最高级别,字符串形式的 URI 引用(以下简称“URI”)具有以下语法

[scheme:]scheme-specific-part[#fragment]

其中方括号 [...] 描述可选组件,字符 : 和 # 代表它们自己。

绝对 URI 指定方案; 一个非绝对的 URI 被称为是相对的。 URI 还根据它们是不透明的还是分层的进行分类。

不透明 URI 是绝对 URI,其特定于方案的部分不以斜杠字符 ('/') 开头。 不透明的 URI 不受进一步解析的影响。 不透明 URI 的一些示例是:

分层 URI 要么是绝对 URI,其特定于方案的部分以斜杠字符开头,要么是相对 URI,即不指定方案的 URI。 分层 URI 的一些示例是:

http://java.sun.com/j2se/1.3/ docs/guide/collections/designfaq.html#28 ../../../demo/jfc/SwingSet2/src/SwingSet2.java file:///~/calendar

分层 URI 需要根据语法进行进一步解析

scheme:path[#fragment]

其中字符 :、/、? 和 # 代表它们自己。 分层 URI 的特定于方案的部分由方案和片段组件之间的字符组成。

如果指定,分层 URI 的权限组件是基于服务器的或基于注册表的。 基于服务器的权限根据熟悉的语法进行解析

[user-info@]host[:port]

其中字符 @ 和 : 代表它们自己。目前使用的几乎所有 URI 方案都是基于服务器的。不以这种方式解析的权限组件被认为是基于注册表的。

如果分层 URI 的路径组件以斜杠字符 ('/') 开头,则它本身就是绝对的;否则是相对的。分层 URI 的路径要么是绝对的,要么是指定权限的,它始终是绝对的。

总而言之,一个 URI 实例有以下九个组成部分:

在给定的实例中,任何特定组件要么未定义,要么具有不同的值。未定义的字符串组件由 null 表示,而未定义的整数组件由 -1 表示。可以将字符串组件定义为将空字符串作为其值;这不等于未定义该组件。

特定组件是否在实例中定义取决于所表示的 URI 的类型。绝对 URI 有一个方案组件。一个不透明的 URI 有一个方案、一个特定于方案的部分,可能还有一个片段,但没有其他组件。分层 URI 总是有一个路径(尽管它可能是空的)和一个特定于方案的部分(至少包含路径),并且可能有任何其他组件。如果权限组件存在并且是基于服务器的,那么将定义主机组件并且可以定义用户信息和端口组件。

URI 实例上的操作 此类支持的关键操作是规范化、解析和相对化。

规范化是删除不必要的“。”的过程。和“..”来自分层 URI 的路径组件的段。每个 ”。”段被简单地删除。仅当“..”段前面有非“..”段时,才会删除“..”段。规范化对不透明的 URI 没有影响。

解析是根据另一个基本 URI 解析一个 URI 的过程。生成的 URI 以 RFC 2396 指定的方式由两个 URI 的组件构成,从原始 URI 中获取未指定的组件。对于分层 URI,原始路径会根据基路径解析,然后进行规范化。例如:

docs/guide/collections/designfaq.html#28 (1)

针对基础 URI http://java.sun.com/j2se/1.3/ 是结果 URI

https://docs.oracle.com/javase/1.3/docs/guide/collections/designfaq.html

解析相对 URI

../../../demo/jfc/SwingSet2/src/SwingSet2.java (2)

反过来,与这个结果相反,

http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java

支持对绝对和相对 URI 的解析,以及在分层 URI 的情况下对绝对和相对路径的解析。 根据任何其他 URI 解析 URI file:///~calendar 只会产生原始 URI,因为它是绝对的。 将上面的相对 URI (2) 与相对基本 URI (1) 解析会产生规范化但仍然是相对的 URI

demo/jfc/SwingSet2/src/SwingSet2.java

最后,相对化是解析的倒数:对于任何两个标准化的 URI u 和 v,

u.relativize(u.resolve(v)).equals(v) and u.resolve(u.relativize(v)).equals(v) .

在构建包含 URI 的文档时,此操作通常很有用,这些 URI 必须尽可能与文档的基本 URI 相关。 例如,将 URI 相对化

https://docs.oracle.com/javase/1.3/docs/guide/index.html

针对基础 URI

http://java.sun.com/j2se/1.3

产生相对 URI docs/guide/index.html。 字符类别 RFC 2396 准确地指定了在 URI 引用的各种组件中允许使用的字符。 以下类别(其中大部分来自该规范)用于描述这些约束:

所有合法 URI 字符的集合由未保留、保留、转义和其他字符组成。

转义八位组、引用、编码和解码 RFC 2396 允许转义八位组出现在用户信息、路径、查询和片段组件中。 转义在 URI 中有两个目的:

  • 在要求 URI 严格遵守 RFC 2396 时,对非 US-ASCII 字符进行编码,不包含任何其他字符。
  • 引用组件中非法的字符。用户信息、路径、查询和片段组件在哪些字符被视为合法和非法方面略有不同。

这些目的在此类中通过三个相关操作来实现:

  • 通过将字符替换为在 UTF-8 字符集中表示该字符的转义八位字节序列来对字符进行编码。例如,欧元货币符号 ('\u20AC') 编码为“%E2%82%AC”。 (偏离 RFC 2396,它没有指定任何特定的字符集。)
  • 通过编码简单地引用非法字符。例如,空格字符通过将其替换为“%20”来引用。 UTF-8 包含 US-ASCII,因此对于 US-ASCII 字符,此转换具有 RFC 2396 所要求的效果。
  • 通过将转义的八位字节序列替换为它在 UTF-8 字符集中表示的字符序列来解码它。 UTF-8 包含 US-ASCII,因此解码具有取消引用任何引用的 US-ASCII 字符以及解码任何编码的非 US-ASCII 字符的效果。如果在解码转义的八位字节时发生解码错误,则错误的八位字节将替换为 '\uFFFD',Unicode 替换字符。

这些操作在该类的构造函数和方法中暴露如下:

  • 单参数构造函数要求在其参数中引用任何非法字符,并保留任何转义的八位字节和其他存在的字符。
  • 多参数构造函数根据它们出现的组件的要求引用非法字符。这些构造函数始终引用百分比字符 ('%')。保留任何其他字符。
  • getRawUserInfo、getRawPath、getRawQuery、getRawFragment、getRawAuthority 和 getRawSchemeSpecificPart 方法以原始形式返回其对应组件的值,而不解释任何转义的八位字节。这些方法返回的字符串可能同时包含转义的八位字节和其他字符,并且不会包含任何非法字符。
  • getUserInfo、getPath、getQuery、getFragment、getAuthority 和 getSchemeSpecificPart 方法解码其相应组件中的任何转义八位字节。这些方法返回的字符串可能同时包含其他字符和非法字符,并且不会包含任何转义的八位位组。
  • toString 方法返回一个包含所有必要引号但可能包含其他字符的 URI 字符串。
  • toASCIIString 方法返回不包含任何其他字符的完全引用和编码的 URI 字符串。

身份 对于任何 URI u,总是这样

new URI(u.toString()).equals(u) .

对于任何不包含冗余语法的 URI u,例如空权限前的两个斜杠(如 file:///tmp/ 中)或主机名后的冒号但没有端口(如 http://java.sun. com: ),并且除了必须引用的字符之外不编码字符,以下标识也成立:

     new URI(u.getScheme(),
             u.getSchemeSpecificPart(),
             u.getFragment())
     .equals(u)

在所有情况下,

     new URI(u.getScheme(),
             u.getUserInfo(), u.getAuthority(),
             u.getPath(), u.getQuery(),
             u.getFragment())
     .equals(u)

如果你是分层的,并且

     new URI(u.getScheme(),
             u.getUserInfo(), u.getHost(), u.getPort(),
             u.getPath(), u.getQuery(),
             u.getFragment())
     .equals(u)

如果 u 是分层的并且没有权限或基于服务器的权限。 URI、URL 和 URN URI 是统一资源标识符,而 URL 是统一资源定位符。因此,抽象地说,每个 URL 都是一个 URI,但并不是每个 URI 都是一个 URL。这是因为有另一个 URI 子类别,统一资源名称 (URN),它命名资源但不指定如何定位它们。上面显示的 mailto、news 和 isbn URI 是 URN 的示例。

URI 和 URL 之间的概念区别体现在此类和 URL 类之间的差异上。

此类的实例表示 RFC 2396 定义的句法意义上的 URI 引用。URI 可以是绝对的,也可以是相对的。 URI 字符串根据通用语法进行解析,而不考虑它指定的方案(如果有)。不执行主机查找(如果有的话),也不构造依赖于方案的流处理程序。相等、散列和比较是根据实例的字符内容严格定义的。换句话说,URI 实例只不过是一个结构化的字符串,它支持比较、规范化、解析和相对化的语法、与方案无关的操作。

相比之下,URL 类的实例表示 URL 的句法组件以及访问它所描述的资源所需的一些信息。 URL 必须是绝对的,也就是说,它必须始终指定一个方案。 URL 字符串根据其方案进行解析。始终为 URL 建立流处理程序,实际上不可能为没有可用处理程序的方案创建 URL 实例。相等和散列取决于主机的方案和 Internet 地址(如果有);比较没有定义。换句话说,URL 是一个结构化的字符串,它支持解析的语法操作以及查找主机和打开到指定资源的连接的网络 I/O 操作。

构造函数摘要

构造函数 描述
URI(String str) 通过解析给定的字符串构造一个 URI。
URI(String scheme, String ssp, String fragment) 从给定的组件构造一个 URI。
URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment) 从给定的组件构造一个分层的 URI。
URI(String scheme, String host, String path, String fragment) 从给定的组件构造一个分层的 URI。
URI(String scheme, String authority, String path, String query, String fragment) 从给定的组件构造一个分层的 URI。

方法总结

修饰符和类型 方法 描述
int compareTo(URI that) 将此 URI 与另一个对象进行比较,该对象必须是 URI。
static URI create(String str) 通过解析给定的字符串创建一个 URI。
boolean equals(Object ob) 测试此 URI 是否与另一个对象相等。
String getAuthority() 返回此 URI 的解码权限组件。
String getFragment() 返回此 URI 的解码片段组件。
String getHost() 返回此 URI 的主机组件。
String getPath() 返回此 URI 的解码路径组件。
int getPort() 返回此 URI 的端口号。
String getQuery() 返回此 URI 的解码查询组件。
String getRawAuthority() 返回此 URI 的原始权限组件。
String getRawFragment() 返回此 URI 的原始片段组件。
String getRawPath() 返回此 URI 的原始路径组件。
String getRawQuery() 返回此 URI 的原始查询组件。
String getRawSchemeSpecificPart() 返回此 URI 的原始方案特定部分。
String getRawUserInfo() 返回此 URI 的原始用户信息组件。
String getScheme() 返回此 URI 的方案组件。
String getSchemeSpecificPart() 返回此 URI 的已解码方案特定部分。
String getUserInfo() 返回此 URI 的已解码用户信息组件。
int hashCode() 返回此 URI 的哈希码值。
boolean isAbsolute() 说明这个URI是否是绝对的。
boolean isOpaque() 说明这个URI是否是不透明的。
URI normalize() 将这个URI的路径规范化。
URI parseServerAuthority() 尝试将此 URI 的权限组件(如果已定义)解析为用户信息、主机和端口组件。
URI relativize(URI uri) 将给定的 URI 与此 URI 相对化。
URI resolve(String str) 通过解析给定的字符串构造一个新的 URI,然后根据这个 URI 解析它。
URI resolve(URI uri) 根据此 URI 解析给定的 URI。
String toASCIIString() 将此 URI 的内容作为 US-ASCII 字符串返回。
String toString() 将此 URI 的内容作为字符串返回。
URL toURL() 从此 URI 构造一个 URL。
从类 java.lang.Object 继承的方法
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

构造函数详细信息

URI

public URI(String str) throws URISyntaxException

通过解析给定的字符串构造一个 URI。

此构造函数完全按照 RFC 2396 附录 A 中的语法指定的方式解析给定的字符串,但以下偏差除外:

  • 允许空权限组件,只要其后跟非空路径、查询组件或片段组件。这允许解析诸如“file:///foo/bar”之类的 URI,这似乎是 RFC 2396 的意图,尽管语法不允许这样做。如果权限组件为空,则未定义用户信息、主机和端口组件。
  • 允许空的相对路径;这似乎是 RFC 2396 的意图,尽管语法不允许这样做。这种偏差的主要后果是,诸如“#foo”之类的独立片段被解析为具有空路径和给定片段的相对 URI,并且可以有效地针对基本 URI 进行解析。
  • 主机组件中的 IPv4 地址按照 RFC 2732 的规定进行严格解析:点分四组地址的每个元素必须包含不超过三个十进制数字。每个元素被进一步限制为不大于 255。
  • 仅包含单个域标签的主机组件中的主机名允许以字母数字字符开头。这似乎是 RFC 2396 第 3.2.2 节的意图,尽管语法不允许这样做。这种偏差的结果是分层 URI 的权限组件(例如 s://123)将解析为基于服务器的权限。
  • 主机组件允许使用 IPv6 地址。 IPv6 地址必须按照 RFC 2732 的规定括在方括号(“[”和“]”)中。IPv6 地址本身必须根据 RFC 2373 进行解析。IPv6 地址进一步限制为描述不超过 16 个字节的地址信息, RFC 2373 中隐含但在语法中无法表达的约束。
  • 只要 RFC 2396 允许转义八位字节,即在用户信息、路径、查询和片段组件中,以及如果权限是基于注册表的权限组件中,则允许其他类别中的字符。这允许 URI 包含 US-ASCII 字符集中以外的 Unicode 字符。

参数:

参数名称 参数描述
str 要解析为 URI 的字符串

Throws:

Throw名称 Throw描述
NullPointerException 如果 str 为空
URISyntaxException 如果给定的字符串违反了 RFC 2396,由上述偏差增强

URI

public URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment) throws URISyntaxException

从给定的组件构造一个分层的 URI。

如果给出了方案,则路径(如果也给出)必须为空或以斜杠字符 ('/') 开头。 否则,新 URI 的一个组成部分可以通过为相应的参数传递 null 或在端口参数的情况下传递 -1 来保持未定义。

此构造函数首先根据 RFC 2396 第 5.2 节第 7 步中指定的规则从给定组件构建 URI 字符串:

  1. 最初,结果字符串为空。
  2. 如果给出了一个方案,则将其附加到结果中,后跟一个冒号字符 (':')。
  3. 如果给出用户信息、主机或端口,则附加字符串“//”。
  4. 如果给出了用户信息,则附加它,后跟一个商业字符('@')。引用任何不在未保留、标点、转义或其他类别中的字符。
  5. 如果给定主机,则附加它。如果主机是文字 IPv6 地址但未包含在方括号中('[' 和 ']'),则添加方括号。
  6. 如果给定端口号,则附加一个冒号字符 (':'),然后是十进制的端口号。
  7. 如果给出了路径,则将其附加。任何不属于未保留、标点符号、转义或其他类别的字符,并且不等于斜杠字符 ('/') 或商业字符 ('@'),都会被引用。
  8. 如果给出查询,则附加一个问号字符 ('?'),然后是查询。任何不是合法 URI 字符的字符都会被引用。
  9. 最后,如果给出一个片段,则附加一个哈希字符('#'),然后是片段。任何不是合法 URI 字符的字符都会被引用。

然后解析生成的 URI 字符串,就像调用 URI(java.lang.String) 构造函数,然后在结果上调用 parseServerAuthority() 方法一样; 这可能会导致抛出 URISyntaxException。

参数:

参数名称 参数描述
scheme 方案名称
userInfo 用户名和授权信息
host 主机名
port 端口号
path 路径
query 查询
fragment 碎片

Throws:

Throw名称 Throw描述
URISyntaxException 如果同时给出了方案和路径,但路径是相对的,如果从给定组件构造的 URI 字符串违反 RFC 2396,或者如果字符串的权限组件存在但不能被解析为基于服务器的权限

URI

public URI(String scheme, String authority, String path, String query, String fragment) throws URISyntaxException

从给定的组件构造一个分层的 URI。

如果给出了方案,则路径(如果也给出)必须为空或以斜杠字符 ('/') 开头。 否则,通过为相应的参数传递 null 可能会使新 URI 的组件未定义。

此构造函数首先根据 RFC 2396 第 5.2 节第 7 步中指定的规则从给定组件构建 URI 字符串:

  1. 最初,结果字符串为空。
  2. 如果给出了一个方案,则将其附加到结果中,后跟一个冒号字符 (':')。
  3. 如果给定了权限,则附加字符串“//”,然后是权限。如果授权包含文字 IPv6 地址,则地址必须括在方括号中('[' 和 ']')。任何不属于未保留、标点、转义或其他类别的字符,并且不等于商业字符 ('@'),都会被引用。
  4. 如果给出了路径,则附加它。任何不属于未保留、标点符号、转义或其他类别的字符,并且不等于斜杠字符 ('/') 或商业字符 ('@'),都会被引用。
  5. 如果给出查询,则附加一个问号字符 ('?'),然后是查询。任何不是合法 URI 字符的字符都会被引用。
  6. 最后,如果给出一个片段,则附加一个哈希字符('#'),然后是片段。任何不是合法 URI 字符的字符都会被引用。

然后解析生成的 URI 字符串,就像调用 URI(java.lang.String) 构造函数,然后在结果上调用 parseServerAuthority() 方法一样; 这可能会导致抛出 URISyntaxException。

参数:

参数名称 参数描述
scheme 方案名称
authority 授权
path 路径
query 查询
fragment 碎片

Throws:

Throw名称 Throw描述
URISyntaxException 如果同时给出了方案和路径,但路径是相对的,如果从给定组件构造的 URI 字符串违反 RFC 2396,或者如果字符串的权限组件存在但不能被解析为基于服务器的权限

URI

public URI(String scheme, String host, String path, String fragment) throws URISyntaxException

从给定的组件构造一个分层的 URI。

通过传递 null 可以使组件保持未定义。

这个便利构造函数就像通过调用七参数构造函数一样工作,如下所示:

new URI(scheme, null, host, -1, path, null, fragment);

参数:

参数名称 参数描述
scheme 方案名称
host 主机名
path 路径
fragment 碎片

Throws:

Throw名称 Throw描述
URISyntaxException 如果从给定组件构造的 URI 字符串违反 RFC 2396

URI

public URI(String scheme, String ssp, String fragment) throws URISyntaxException

从给定的组件构造一个 URI。

通过传递 null 可以使组件保持未定义。

此构造函数首先使用给定的组件构建一个字符串形式的 URI,如下所示:

  1. 最初,结果字符串为空。
  2. 如果给出了一个方案,则将其附加到结果中,后跟一个冒号字符 (':')。
  3. 如果给出了特定于方案的部分,则将其附加。 任何不是合法 URI 字符的字符都会被引用。
  4. 最后,如果给出一个片段,则将一个哈希字符 ('#') 附加到字符串,然后是片段。 任何不是合法 URI 字符的字符都会被引用。

然后解析生成的 URI 字符串,以创建新的 URI 实例,就像调用 URI(java.lang.String) 构造函数一样; 这可能会导致抛出 URISyntaxException。

参数:

参数名称 参数描述
scheme 方案名称
ssp 方案特定部分
fragment 碎片

Throws:

Throw名称 Throw描述
URISyntaxException 如果从给定组件构造的 URI 字符串违反 RFC 2396

方法详情

create

public static URI create(String str)

通过解析给定的字符串创建一个 URI。

这个方便的工厂方法就像调用 URI(java.lang.String) 构造函数一样工作; 构造函数抛出的任何 URISyntaxException 都会被捕获并包装在一个新的 IllegalArgumentException 对象中,然后抛出该对象。

提供此方法用于已知给定字符串是合法 URI 的情况,例如在程序中声明的 URI 常量,因此如果字符串不这样解析将被视为编程错误。 直接抛出 URISyntaxException 的构造函数应该用于从用户输入或其他可能容易出错的源构造 URI 的情况。

参数:

参数名称 参数描述
str 要解析为 URI 的字符串

返回:

新的 URI

Throws:

Throw名称 Throw描述
NullPointerException 如果 str 为空
IllegalArgumentException 如果给定的字符串违反 RFC 2396

parseServerAuthority

public URI parseServerAuthority() throws URISyntaxException

尝试将此 URI 的权限组件(如果已定义)解析为用户信息、主机和端口组件。

如果这个 URI 的权限组件已经被识别为基于服务器的,那么它已经被解析为用户信息、主机和端口组件。在这种情况下,或者如果此 URI 没有权限组件,则此方法仅返回此 URI。

否则,此方法会再次尝试将权限组件解析为用户信息、主机和端口组件,并抛出异常,说明无法以这种方式解析权限组件的原因。

之所以提供此方法,是因为 RFC 2396 中指定的通用 URI 语法不能始终区分格式错误的基于服务器的权限和合法的基于注册表的权限。因此,它必须将前者的某些实例视为后者的实例。例如,URI 字符串“//foo:bar”中的权限组件不是基于服务器的合法权限,但作为基于注册表的权限是合法的。

在许多常见情况下,例如当工作 URI 已知为 URN 或 URL 时,所使用的分层 URI 将始终基于服务器。因此,它们必须按原样解析或视为错误。在这些情况下,声明如

URI u = new URI(str).parseServerAuthority();

可用于确保 u 始终引用一个 URI,如果它具有权限组件,则具有基于服务器的权限以及适当的用户信息、主机和端口组件。 调用此方法还确保如果无法以这种方式解析权限,则可以根据抛出的异常发出适当的诊断消息。

返回:

一个URI,其权限字段已被解析为基于服务器的权限

Throws:

Throw名称 Throw描述
URISyntaxException 如果此 URI 的权限组件已定义但不能根据 RFC 2396 解析为基于服务器的权限

normalize

public URI normalize()

规范化此 URI 的路径。

如果这个 URI 是不透明的,或者如果它的路径已经是正常的形式,那么这个 URI 被返回。 否则,将构造一个与此 URI 相同的新 URI,除了它的路径是通过以符合 RFC 2396,第 5.2 节,第 6 步,子步骤 c 到 f 的方式规范化此 URI 的路径来计算的; 那是:

  1. 全部“.” 段被删除。
  2. 如果“..”段前面有一个非“..”段,则这两个段都被删除。 重复此步骤,直到不再适用。
  3. 如果路径是相对的,并且如果它的第一段包含一个冒号字符(':'),那么一个“.” 段是前置的。 这可以防止具有诸如“a:b/c/d”之类路径的相对 URI 稍后被重新解析为具有“a”方案和“b/c/d”方案特定部分的不透明 URI . (偏离 RFC 2396)

如果在它们之前没有足够的非“..”段以允许将其删除,则规范化路径将从一个或多个“..”段开始。 规范化路径将以“。”开头。 如果在上面的步骤 3 中插入了一个片段。 否则,规范化路径将不包含任何“。” 或“..”段。

返回:

与此 URI 等效的 URI,但其路径为正常格式

resolve

public URI resolve(URI uri)

根据此 URI 解析给定的 URI。

如果给定的 URI 已经是绝对的,或者如果这个 URI 是不透明的,则返回给定的 URI。

如果给定 URI 的片段组件已定义,其路径组件为空,并且其方案、权限和查询组件未定义,则返回具有给定片段但所有其他组件与该 URI 相同的 URI。 这允许表示独立片段引用的 URI,例如“#foo”,可以有效地针对基本 URI 进行解析。

否则,此方法以与 RFC 2396 第 5.2 节一致的方式构造新的分层 URI; 那是:

  1. 使用此 URI 的方案以及给定 URI 的查询和片段组件构造一个新的 URI。
  2. 如果给定 URI 具有权限组件,则新 URI 的权限和路径取自给定 URI。
  3. 否则,从该 URI 复制新 URI 的权限组件,其路径计算如下:
    1. 如果给定 URI 的路径是绝对路径,则新 URI 的路径取自给定 URI。
    2. 否则,给定 URI 的路径是相对的,因此新 URI 的路径是通过根据该 URI 的路径解析给定 URI 的路径来计算的。 这是通过将此 URI 路径的最后一段(如果有的话)与给定 URI 的路径连接起来,然后像调用 normalize 方法一样对结果进行规范化来完成的。

此方法的结果是绝对的,当且仅当此 URI 是绝对的或给定的 URI 是绝对的。

参数:

参数名称 参数描述
uri 要针对此 URI 解析的 URI

返回:

生成的 URI

Throws:

Throw名称 Throw描述
NullPointerException 如果 uri 为空

resolve

public URI resolve(String str)

通过解析给定的字符串构造一个新的 URI,然后根据这个 URI 解析它。

这种便捷方法的工作方式就像调用它等同于评估表达式 resolve(URI.create(str))。

参数:

参数名称 参数描述
str 要解析为 URI 的字符串

返回:

生成的 URI

Throws:

Throw名称 Throw描述
NullPointerException 如果 str 为空
IllegalArgumentException 如果给定的字符串违反 RFC 2396

relativize

public URI relativize(URI uri)

将给定的 URI 与此 URI 相对化。

给定 URI 与此 URI 的相对化计算如下:

  1. 如果此 URI 或给定 URI 不透明,或者如果两个 URI 的方案和权限组件不相同,或者如果此 URI 的路径不是给定 URI 路径的前缀,则给定 返回 URI。
  2. 否则,使用从给定 URI 获取的查询和片段组件以及通过从给定 URI 路径的开头删除此 URI 路径来计算的路径组件来构造新的相对分层 URI。

参数:

参数名称 参数描述
uri 要针对此 URI 进行相对化的 URI

返回:

生成的 URI

Throws:

Throw名称 Throw描述
NullPointerException 如果 uri 为空

toURL

public URL toURL() throws MalformedURLException

从此 URI 构造一个 URL。

这种便捷方法的工作方式就好像调用它等同于在首先检查此 URI 是否为绝对值之后评估表达式 new URL(this.toString())。

返回:

从此 URI 构造的 URL

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果此 URL 不是绝对的
MalformedURLException 如果找不到 URL 的协议处理程序,或者在构造 URL 时发生了其他错误

getScheme

public String getScheme()

返回此 URI 的方案组件。

URI 的方案组件(如果已定义)仅包含字母数字类别和字符串“-.+”中的字符。 方案总是以字母字符开头。

URI 的方案组件不能包含转义的八位字节,因此此方法不执行任何解码。

返回:

此 URI 的方案组件,如果方案未定义,则为 null

isAbsolute

public boolean isAbsolute()

判断这个 URI 是否是绝对的。

当且仅当它具有方案组件时,URI 才是绝对的。

返回:

当且仅当此 URI 是绝对的,则为 true

isOpaque

public boolean isOpaque()

判断此 URI 是否不透明。

当且仅当 URI 是绝对的并且其特定于方案的部分不以斜杠字符 ('/') 开头时,URI 才是不透明的。 一个不透明的 URI 有一个方案,一个特定于方案的部分,可能还有一个片段; 所有其他组件都未定义。

返回:

当且仅当此 URI 不透明时才为 true

getRawSchemeSpecificPart

public String getRawSchemeSpecificPart()

返回此 URI 的原始方案特定部分。 特定于方案的部分永远不会未定义,尽管它可能为空。

URI 的特定于方案的部分仅包含合法的 URI 字符。

返回:

此 URI 的原始方案特定部分(从不为空)

getSchemeSpecificPart

public String getSchemeSpecificPart()

返回此 URI 的已解码方案特定部分。

此方法返回的字符串与 getRawSchemeSpecificPart 方法返回的字符串相同,但所有转义八位字节序列均已解码。

返回:

此 URI 的解码方案特定部分(从不为空)

getRawAuthority

public String getRawAuthority()

返回此 URI 的原始权限组件。

URI 的权限组件(如果已定义)仅包含商业字符 ('@') 以及未保留、标点、转义和其他类别中的字符。 如果权限是基于服务器的,则进一步限制它具有有效的用户信息、主机和端口组件。

返回:

此 URI 的原始权限组件,如果权限未定义,则为 null

getAuthority

public String getAuthority()

返回此 URI 的解码权限组件。

此方法返回的字符串与 getRawAuthority 方法返回的字符串相同,但所有转义八位字节序列均已解码。

返回:

此 URI 的已解码权限组件,如果权限未定义,则为 null

getRawUserInfo

public String getRawUserInfo()

返回此 URI 的原始用户信息组件。

URI 的用户信息组件(如果已定义)仅包含未保留、标点、转义和其他类别中的字符。

返回:

此 URI 的原始用户信息组件,如果用户信息未定义,则为 null

getUserInfo

public String getUserInfo()

返回此 URI 的已解码用户信息组件。

此方法返回的字符串与 getRawUserInfo 方法返回的字符串相同,只是所有转义的八位字节序列都被解码。

返回:

此 URI 的已解码用户信息组件,如果用户信息未定义,则为 null

getHost

public String getHost()

返回此 URI 的主机组件。

URI 的主机组件(如果已定义)将具有以下形式之一:

  • 由一个或多个标签组成的域名,这些标签由句点字符 ('.') 分隔,可选地后跟一个句点字符。 每个标签都由字母数字字符和连字符 ('-') 组成,但连字符永远不会作为标签中的第一个或最后一个字符出现。 由两个或多个标签组成的域名的最右侧标签以字母字符开头。
  • digit+.digit+.digit+.digit+ 形式的点分四线 IPv4 地址,其中没有数字序列长于三个字符,并且没有序列的值大于 255。
  • 用方括号('[' 和 ']')括起来的 IPv6 地址,由十六进制数字、冒号字符(':')和可能嵌入的 IPv4 地址组成。 IPv6 地址的完整语法在 RFC 2373:IPv6 Addressing Architecture 中指定。

URI 的主机组件不能包含转义的八位字节,因此此方法不执行任何解码。

返回:

此 URI 的主机组件,如果主机未定义,则为 null

getPort

public int getPort()

返回此 URI 的端口号。

URI 的端口组件(如果已定义)是一个非负整数。

返回:

此 URI 的端口组件,如果端口未定义,则为 -1

getRawPath

public String getRawPath()

返回此 URI 的原始路径组件。

URI 的路径组件(如果已定义)仅包含斜杠字符 ('/')、商业字符 ('@') 以及未保留、标点、转义和其他类别中的字符。

返回:

此 URI 的路径组件,如果路径未定义,则为 null

getPath

public String getPath()

返回此 URI 的解码路径组件。

此方法返回的字符串与 getRawPath 方法返回的字符串相同,只是所有转义八位字节序列都被解码。

返回:

此 URI 的解码路径组件,如果路径未定义,则为 null

getRawQuery

public String getRawQuery()

返回此 URI 的原始查询组件。

URI 的查询组件(如果已定义)仅包含合法的 URI 字符。

返回:

此 URI 的原始查询组件,如果查询未定义,则为 null

getQuery

public String getQuery()

返回此 URI 的解码查询组件。

此方法返回的字符串与 getRawQuery 方法返回的字符串相同,但所有转义八位位组序列均已解码。

返回:

此 URI 的已解码查询组件,如果查询未定义,则为 null

getRawFragment

public String getRawFragment()

返回此 URI 的原始片段组件。

URI 的片段组件(如果已定义)仅包含合法的 URI 字符。

返回:

此 URI 的原始片段组件,如果片段未定义,则为 null

getFragment

public String getFragment()

返回此 URI 的解码片段组件。

此方法返回的字符串与 getRawFragment 方法返回的字符串相同,但所有转义八位字节序列均已解码。

返回:

此 URI 的已解码片段组件,如果片段未定义,则为 null

equals

public boolean equals(Object ob)

测试此 URI 是否与另一个对象相等。

如果给定对象不是 URI,则此方法立即返回 false。

要使两个 URI 被视为相等,要求两者都是不透明的或都是分层的。它们的方案必须要么都是未定义的,要么是相等的,不考虑大小写。它们的片段必须要么都是未定义的,要么是相等的。

要使两个不透明的 URI 被视为相等,它们的特定于方案的部分必须相等。

对于被认为相等的两个分层 URI,它们的路径必须相等,并且它们的查询必须要么都未定义,要么相等。他们的权限必须要么都是未定义的,要么都是基于注册表的,或者都是基于服务器的。如果它们的权限被定义并且基于注册,那么它们必须是平等的。如果它们的权限被定义并且是基于服务器的,那么它们的主机必须相同而不考虑大小写,它们的端口号必须相同,并且它们的用户信息组件必须相同。

在测试两个 URI 的用户信息、路径、查询、片段、权限或特定于方案的部分是否相等时,将比较这些组件的原始形式而不是编码形式,并且比较转义八位字节的十六进制数字而不考虑案件。

此方法满足 Object.equals 方法的一般约定。

覆盖:

类 Object 中的等于

参数:

参数名称 参数描述
ob 此对象要与之比较的对象

返回:

当且仅当给定对象是与此 URI 相同的 URI 时,才为 true

hashCode

public int hashCode()

返回此 URI 的哈希码值。 哈希码基于 URI 的所有组件,并满足 Object.hashCode 方法的一般约定。

覆盖:

类 Object 中的 hashCode

返回:

此 URI 的哈希码值

compareTo

public int compareTo(URI that)

将此 URI 与另一个对象进行比较,该对象必须是 URI。

在比较两个 URI 的对应组件时,如果一个组件未定义但另一个已定义,则认为第一个小于第二个。 除非另有说明,否则字符串组件将根据 String.compareTo 方法定义的自然、区分大小写的顺序进行排序。 通过比较它们的原始形式而不是它们的编码形式来比较受编码的字符串组件。

URI 的顺序定义如下:

  • 两个具有不同方案的 URI 根据它们方案的顺序排序,不考虑大小写。
  • 分层 URI 被认为小于具有相同方案的不透明 URI。
  • 具有相同方案的两个不透明 URI 根据其方案特定部分的顺序进行排序。
  • 具有相同方案和方案特定部分的两个不透明 URI 根据其片段的顺序进行排序。
  • 两个具有相同方案的分层 URI 根据其权限组件的顺序进行排序:
    • 如果两个权限组件都是基于服务器的,那么 URI 会根据它们的用户信息组件进行排序; 如果这些组件相同,则 URI 将根据其主机的顺序进行排序,而不考虑大小写; 如果主机相同,则 URI 将根据其端口的顺序进行排序。
    • 如果一个或两个权限组件是基于注册表的,则 URI 根据其权限组件的顺序进行排序。
  • 最后,将具有相同方案和权限组件的两个分层URI按照路径的顺序进行排序; 如果它们的路径相同,则根据查询的顺序对它们进行排序; 如果查询相同,则根据其片段的顺序对其进行排序。

此方法满足 Comparable.compareTo 方法的一般约定。

指定者:

接口 ComparableURI 中的 compareTo

参数:

参数名称 参数描述
that 此 URI 要与之比较的对象

返回:

负整数、零或正整数,因为此 URI 小于、等于或大于给定 URI

Throws:

Throw名称 Throw描述
ClassCastException 如果给定对象不是 URI

toString

public String toString()

将此 URI 的内容作为字符串返回。

如果此 URI 是通过调用此类中的构造函数之一创建的,则返回与原始输入字符串或根据最初给定组件计算的字符串等效的字符串(视情况而定)。 否则,此 URI 是通过规范化、解析或相对化创建的,因此根据 RFC 2396 第 5.2 节第 7 步中指定的规则从此 URI 的组件构造一个字符串。

覆盖:

类 Object 中的 toString

返回:

此 URI 的字符串形式

toASCIIString

public String toASCIIString()

将此 URI 的内容作为 US-ASCII 字符串返回。

如果此 URI 不包含其他类别中的任何字符,则调用此方法将返回与调用 toString 方法相同的值。 否则,此方法就像通过调用该方法然后对结果进行编码一样工作。

返回:

此 URI 的字符串形式,根据需要进行编码,使其仅包含 US-ASCII 字符集中的字符