java.net

接口
异常
java.lang.Object
  继承者 java.net.URI
所有已实现的接口:
Serializable, Comparable< URI>

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

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

除了以下提到的一些细微不同之处外,此类的实例代表一个 URI 引用,这在以下文档中定义:RFC 2396: Uniform Resource Identifiers (URI):Generic Syntax;在此文件中对其内容又进行了修正:RFC 2732:Format for Literal IPv6 Addresses in URLs。字面值 IPv6 地址格式还支持 scope_ids。scope_ids 的语法和用法在此处描述。此类提供了用于从其组成部分或通过解析其字符串形式创建 URI 实例的构造方法、用于访问实例的各个不同组成部分的方法,以及用于对 URI 实例进行规范化、解析和相对化的方法。此类的实例不可变。

URI 语法和组成部分

在最高级别上,字符串形式的 URI 引用(以下简写为 "URI")语法如下
[ scheme : ] scheme-specific-part[ # fragment]
其中,方括号 [...] 用于描述可选组成部分,字符 :# 代表它们自身。

绝对 URI 指定了方案 (scheme);非绝对的 URI 称为相对 URI。URI 还可以根据其是否为不透明的分层的 进行分类。

不透明 URI 为绝对 URI,其特定于方案的部分不是以斜线字符 ('/') 开始。不透明 URI 无法进行进一步解析。下面是不透明 URI 的一些示例:

mailto:java-net@java.sun.com
news:comp.lang.java
urn:isbn:096139210x

分层 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 :][ // authority][ path][ ? query][ # fragment]
其中, :/?# 代表它们自身。分层 URI 的特定于方案的部分包含方案和片段部分之间的字符。

分层 URI 的授权组成部分(如果指定)为基于服务器的基于注册表的。基于服务器的授权按照如下众所周知的语法进行解析:

[ user-info @] host[ : port]
其中,字符 @: 代表它们自身。几乎当前使用的所有 URI 方案都是基于服务器的。不能采用这种方式解析的授权组成部分被视为基于注册表的。

如果分层 URI 的路径组成部分以斜线字符 ('/') 开始,则称此 URI 本身为绝对的;否则它为相对的。分层 URI 或者为绝对的,或者指定了授权的路径,它始终为绝对的。

如上所述,URI 实例具有以下九个组成部分:

组成部分 类型
方案 String
特定于方案的部分 String
授权 String
用户信息 String
主机 String
端口 int
路径 String
查询 String
片段 String
在给定实例中,任何特殊组成部分都或者为 未定义的,或者为 已定义的,并且有不同的值。未定义的字符串组成部分由 null 表示,未定义的整数组成部分由 -1 表示。已定义的字符串组成部分的值可以为空字符串;这与未定义的组成部分不等效。

实例中特定的组成部分是已定义的还是未定义的取决于所代表的 URI 类型。绝对 URI 具有方案组成部分。不透明的 URI 具有一个方案、一个特定于方案的部分,以及可能会有一个片段,但是没有其他组成部分。分层 URI 总是有一个路径(尽管可能为空)和一个特定于方案的部分(它至少包含一个路径),还可以包含任何其他组成部分。如果有授权组成部分且它又是基于服务器的,则主机组成部分将被定义,也有可能定义用户信息和端口组成部分。

针对 URI 实例的运算

此类支持的主要运算有 规范化解析相对化 运算。

规范化 是将分层 URI 的路径组成部分中的不必要的 "."".." 部分移除的过程。每个 "." 部分都将被移除。".." 部分也被移除,除非它前面有一个非 ".." 部分。规范化对不透明 URI 不产生任何效果。

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

docs/guide/collections/designfaq.html#28          (1)
根据基本 URI http://java.sun.com/j2se/1.3/ 解析,结果为 URI
http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28
解析相对 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 (1) 解析相对 URI (2) 将生成规范的但依然是相对的 URI
demo/jfc/SwingSet2/src/SwingSet2.java

最后,相对化 是解析的逆过程:对于任何两个规范的 URI uv

u .relativize( u .resolve( v )).equals( v )  和
u .resolve( u .relativize( v )).equals( v )
此运算在下面的场合非常有用:构造一个包含 URI 的文档,该 URI 必须尽可能是根据文档的基本 URI 建立的相对 URI。例如,相对化 URI
http://java.sun.com/j2se/1.3/docs/guide/index.html
根据基本 URI
http://java.sun.com/j2se/1.3
生成了相对 URI docs/guide/index.html

字符分类

RFC 2396 精确指出 URI 引用中的各个不同组成部分允许使用的字符。以下分类大部分取自该规范,这些约束的用法描述如下:
alpha US-ASCII 字母字符,'A' 到 'Z' 以及 'a' 到 'z'
digit US-ASCII 十进制数字符,'0' 到 '9'
alphanum 所有 alphadigit 字符
unreserved     所有 alphanum 字符及字符串 "_-!.~'()*" 中包含的字符
punct 字符串 ",;:$&+=" 中包含的字符
reserved 所有 punct 字符及字符串 "?/[]@" 中包含的字符
escaped 转义八位组,即三部分组合:百分号 ('%') 后跟两个十六进制数('0'-'9''A'-'F''a'-'f'
other 未包含在 US-ASCII 字符集中的 Unicode 字符不是控制字符(根据 Character.isISOControl 方法),并且不是空格字符(根据 Character.isSpaceChar 方法)与 RFC 2396 有些出入,RFC 2396 限制为 US-ASCII)

全部合法 URI 字符集包含 unreservedreservedescapedother 字符。

转义八位组、引用、编码和解码

RFC 2396 允许用户信息、路径、查询和片段组成部分中包含转义八位组。转义在 URI 中实现两个目的:
  • 当要求 URI 不能包含任何 other 字符以严格遵守 RFC 2396 时,需要对非 US-ASCII 字符进行编码

  • 引用 组成部分中的非法字符。用户信息、路径、查询和片段组成部分在判断哪些字符合法哪些字符非法上稍有不同。

在此类中由三个相关的运算实现了这两个目的:
  • 字符的编码 方式是,用代表该字符在 UTF-8 字符集中的字符的转义八位组序列取代该字符。例如,欧元符号 ('\u20AC') 编码后为 "%E2%82%AC"与 RFC 2396 有些出入,RFC 2396 未指定任何特殊字符集)

  • 非法字符通过简单地对它进行编码来引用。例如,空格字符,用 "%20" 取代它来进行引用。UTF-8 包含 US-ASCII,因此对于 US-ASCII 字符,此转换具有的效果与 RFC 2396 的要求相同。

  • 对转义八位组序列进行解码 的方法是,用它所代表的 UTF-8 字符集中的字符的序列将它取代。UTF-8 包含 US-ASCII,因此解码具有对引用的任何 US-ASCII 字符取消引用的效果,以及对任何编码的非 US-ASCII 字符进行解码的效果。如果在对转义八位组进行解码时出现解码错误,则出错的八位组用 Unicode 替换字符 '\uFFFD' 取代。

这些运算在此类的构造方法和方法中公开,如下所示:
  • 单参数构造方法要求对参数中的任何非法字符都必须引用,并保留出现的任何转义八位组和 other 字符。

  • 多参数构造方法根据其中出现的组成部分的需要对非法字符进行引用。百分号字符 ('%') 始终通过这些构造方法引用。任何 other 字符都将被保留。

  • getRawUserInfogetRawPathgetRawQuerygetRawFragmentgetRawAuthoritygetRawSchemeSpecificPart 方法以原始形式返回它们的相应组成部分的值,不解释任何转义八位组。由这些方法返回的字符串有可能包含转义八位组和 other 字符,但不包含任何非法字符。

  • getUserInfogetPathgetQuerygetFragmentgetAuthoritygetSchemeSpecificPart 方法解码相应的组成部分中的任何转义八位组。由这些方法返回的字符串有可能包含 other 字符和非法字符,但不包含任何转义八位组。

  • toString 返回带所有必要引用的 URI 字符串,但它可能包含 other 字符。

  • toASCIIString 方法返回不包含任何 other 字符的、完全引用的和经过编码的 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 )
如果 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),它命名资源但不指定如何定位资源。上面的 mailtonewsisbn URI 都是 URN 的示例。

URI 和 URL 概念上的不同反映在此类和 URL 类的不同中。

此类的实例代表由 RFC 2396 定义的语法意义上的一个 URI 引用。URI 可以是绝对的,也可以是相对的。对 URI 字符串按照一般语法进行解析,不考虑它所指定的方案(如果有)不对主机(如果有)执行查找,也不构造依赖于方案的流处理程序。相等性、哈希计算以及比较都严格地根据实例的字符内容进行定义。换句话说,一个 URI 实例和一个支持语法意义上的、依赖于方案的比较、规范化、解析和相对化计算的结构化字符串差不多。

作为对照,URL 类的实例代表了 URL 的语法组成部分以及访问它描述的资源所需的信息。URL 必须是绝对的,即它必须始终指定一个方案。URL 字符串按照其方案进行解析。通常会为 URL 建立一个流处理程序,实际上无法为未提供处理程序的方案创建一个 URL 实例。相等性和哈希计算依赖于方案和主机的 Internet 地址(如果有);没有定义比较。换句话说,URL 是一个结构化字符串,它支持解析的语法运算以及查找主机和打开到指定资源的连接之类的网络 I/O 操作。

从以下版本开始:
1.4
另请参见:
RFC 2279: UTF-8, a transformation format of ISO 10646,
RFC 2373: IPv6 Addressing Architecture,
RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax,
RFC 2732: Format for Literal IPv6 Addresses in URLs,
URISyntaxException, 序列化表格

构造方法摘要
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()
          以 US-ASCII 字符串形式返回此 URI 的内容。
 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。

  • 主机组成部分中的主机名如果只包含一个单独的域标签,则允许其以 alphanum 字符开始。这似乎是 RFC 2396 的 3.2.2 节的意愿,尽管其语法不允许这样。此细微不同带来的结果是,分层 URI 的授权组成部分(比如 s://123)将作为基于服务器的授权进行解析。

  • 主机组成部分允许使用 IPv6 地址。IPv6 地址必须括在方括号 ('['']') 中,正如 RFC 2732 指定的一样。IPv6 地址本身必须按照 RFC 2373 进行解析。IPv6 地址进一步约束为只能描述不超过十六个字节的地址信息,该约束在 RFC 2373 隐式给出,没有在语法中明确说明。

  • 只要 RFC 2396 允许转义八位组,就允许使用其他类别中的字符,即用户信息、路径、查询和片段组成部分以及授权组成部分(如果授权是基于注册表的)中的内容。这样,除了 US-ASCII 字符集中的字符,URI 中还可以包含 Unicode 字符。

参数:
str - 要解析为 URI 的字符串
抛出:
NullPointerException - 如果 strnull
URISyntaxException - 如果给定字符串违背 RFC 2396,正如上述细微不同的补充

URI

public URI(String scheme,
           String userInfo,
           String host,
           int port,
           String path,
           String query,
           String fragment)
    throws URISyntaxException
根据给定的组成部分构造一个分层 URI。

如果给定了方案,则路径(如果也给定)必须为空或以斜线字符 ('/') 开始。否则通过为相应的参数传入 null,或者在 port 参数的情况下,传入 -1,新 URI 的组成部分可能保留为未定义。

此构造方法首先根据 RFC 2396 中的 5.2 节的步骤 7 指定的规则从给定的组成部分构建一个 URI 字符串:

  1. 起初,结果字符串为空。

  2. 如果给定了方案,则将方案添加到结果后面,后面再加一个冒号 (':') 字符。

  3. 如果给定了用户信息、主机或端口,则添加 "//" 字符串。

  4. 如果给定了用户信息,则添加该信息,之后是“商用 at”字符 ('@')。任何不属于 unreservedpunctescapedother 类别的字符都应该进行 引用

  5. 如果给定了主机,则添加该主机。如果主机为字面值 IPv6 地址但未括在方括号 ('['']') 中,则添加方括号。

  6. 如果给定了端口名,则添加一个冒号字符 (':'),之后是十进制形式的端口号。

  7. 如果给定了路径,则添加该路径。任何不属于 unreservedpunctescapedother 类别的字符,以及不等于斜线字符 ('/') 或“商用 at”字符 ('@') 的字符都应该进行引用。

  8. 如果给定了查询,则添加一个问号字符 ('?'),之后是查询。任何不是合法 URI 字符的字符都应该进行引用。

  9. 最后,如果给定了片段,则添加一个井字符 ('#'),之后是片段。任何非法的 URI 字符都应该进行引用。

然后对得到的 URI 字符串进行解析,正如调用 URI(String) 构造方法一样,然后根据结果情况调用 parseServerAuthority();这可能导致抛出 URISyntaxException

参数:
scheme - 方案名
userInfo - 用户信息和授权信息
host - 主机名
port - 端口名
path - 路径
query - 查询
fragment - 片段
抛出:
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 地址,则该地址必须括在方括号 ('['']') 中。任何不属于 unreservedpunctescapedother 类别的字符,以及不等于“商用 at”字符 ('@') 的字符都应该进行引用

  4. 如果给定了路径,则添加该路径。任何不属于 unreservedpunctescapedother 类别的字符,以及不等于斜线字符 ('/') 或“商用 at”字符 ('@') 的字符都应该进行引用。

  5. 如果给定了查询,则添加一个问号字符 ('?'),之后是查询。任何不是合法 URI 字符的字符都应该进行引用。

  6. 最后,如果给定了片段,则添加一个井字符 ('#'),之后是片段。任何非法的 URI 字符都应该进行引用。

然后对得到的 URI 字符串进行解析,正如调用 URI(String) 构造方法一样,然后根据结果情况调用 parseServerAuthority();这可能导致抛出 URISyntaxException

参数:
scheme - 方案名
authority - 授权
path - 路径
query - 查询
fragment - 片段
抛出:
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 - 片段
抛出:
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(String) 构造方法一样;这可能导致抛出 URISyntaxException

参数:
scheme - 方案名
ssp - 特定于方案的部分
fragment - 片段
抛出:
URISyntaxException - 如果根据给定的组成部分构造的 URI 字符串违背 RFC 2396
方法详细信息

create

public static URI create(String str)
通过解析给定的字符串创建 URI。

此便捷工厂方法的工作方式类似于调用 URI(String) 构造方法;由该构造方法抛出的任何 URISyntaxException 都被捕获,并包装到一个新的 IllegalArgumentException 对象中,然后抛出此对象。

此方法的使用场合是:已知给定的字符串是合法的 URI(例如,程序中声明的 URI 常量),该字符串无法这样解析时将被视为编程错误。当 URI 从用户输入或从其他易于引起错误的源构造时,应该使用直接抛出 URISyntaxException 的构造方法。

参数:
str - 要解析为 URI 的字符串
返回:
新的 URI
抛出:
NullPointerException - 如果 strnull
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
抛出:
URISyntaxException - 如果此 URI 的授权部分已定义,但是按照 RFC2396 不能解析为基于服务器的授权

normalize

public URI normalize()
规范化此 URI 的路径。

如果此 URI 为不透明的,或者其路径已经是规范形式,则返回此 URI。否则,将构造一个新的 URI,它与此 URI 基本相同,只有路径是通过规范化此 URI 的路径计算得出的,规范化的方式与 RFC 2396 的 5.2 节的步骤 6 的子步骤 c 到 f 一致;即:

  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 的片段组成部分已定义,其路径组成部分为空,并且其方案、授权及查询组成部分未定义,则返回一个 URL,它是由一个给定的片段及本 URL 的所有其他组成部分构成。这允许表示单独片段引用的 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 路径的其他所有部分与给定 URI 的路径串联起来,然后将得到的结果规范化(正如调用 normalize 方法一样)。

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

参数:
uri - 要根据此 URI 解析的 URI
返回:
结果 URI
抛出:
NullPointerException - 如果 urinull