Java URL 构造函数忽略路径段

问题描述

我正在使用 Java URL 构造函数“URL(URL context,String spec)” found here 但构造的 URL 不是我所期望的 - 它遗漏了上下文参数中提供的路径段。

以这段代码为例

new URL(new URL("http://asdf.com/z"),"a/b/c");

生成一个带有值的 URL

http://asdf.com/a/b/c

所以它漏掉了“z”路径段。

我有两个问题:

  1. java 文档中第一个参数的“上下文”是什么意思?我在 URL 规范中找不到它的提及,也没有在 Java 文档中找到它。
  2. 是否遗漏了“z”预期行为?

谢谢!

解决方法

java doc中第一个参数“context”是什么意思?

它就像 spec 参数的“基本 URL”。如果 contexthttps://example.com,而 spec/foo,则构造函数将创建 https://example.com/foo。它类似于(但不完全相同,我们稍后会看到)询问“我目前在 https://example.com,我想转到 /foo,我的最终 URL 是什么?”

是否遗漏了“z”预期行为?

是的。如果您按照 RFC 2396 中关于此案例的 rules of resolving a relative URL against an base URL 进行操作,您将到达此步骤:

(6) 如果到了这一步,那么我们正在解析一个相对路径 参考。相对路径需要和base合并 URI 的路径。虽然有很多方法可以做到这一点,但我们将 描述一个使用单独字符串缓冲区的简单方法。

(a) 除了基本 URI 的路径组件的最后一段之外的所有内容都是 复制到缓冲区。换句话说,后面的任何字符 最后一个(最右边的)斜杠字符(如果有)被排除在外。

(b) 引用的路径组件被附加到缓冲区 字符串。

这里的“最后一段”是指z,它添加到缓冲区中。紧接着,路径 a/b/c “被附加到缓冲区”。从步骤 (c) 开始处理删除 ...,这在此处无关紧要。

请注意,RFC 2386 并未规定您必须以这种方式实现算法,但无论您的实现是什么,您的输出都必须与该算法的输出匹配:

上述算法旨在提供一个示例,通过该示例 可以测试实现的输出——实现 算法本身不是必需的。

所以是的,这是意料之中的。要保留 /z,您应该在 / 之后添加另一个 z

new URL(new URL("http://asdf.com/z/"),"a/b/c")

这样“最后一段”就变成了空字符串。

,

您可以将上下文视为文件系统中的当前目录。
使用上下文“http://asdf.com/z”,当前目录是“http://asdf.com/”,并使用“a/b/c”作为规范将产生一个完整路径“http:/ /asdf.com/a/b/c”。