当相对 URI 包含空路径时,Java 的 URI.resolve 是否与 RFC 3986 不兼容?
我相信Java的URI.resolve方法的定义和实现与RFC 3986第5.2.2节不兼容。我知道Java API定义了该方法的工作原理,如果现在更改它,它将破坏现有的应用程序,但我的问题是:任何人都可以确认我的理解,即此方法与RFC 3986不兼容?
我使用这个问题中的示例:java.net.URI 仅针对查询字符串进行解析,我将将其复制到此处:
我正在尝试使用JDK java.net.URI构建URI。我想追加到一个绝对URI对象,一个查询(在字符串中)。例如:
URI base = new URI("http://example.com/something/more/long");
String queryString = "query=http://local:282/rand&action=aaaa";
URI query = new URI(null, null, null, queryString, null);
URI result = base.resolve(query);
理论(或我认为)是决心应该回归:
http://example.com/something/more/long?query=http://local:282/rand&action=aaaa
但我得到的是:
http://example.com/something/more/?query=http://local:282/rand&action=aaaa
我对 RFC 3986 第 5.2.2 节的理解是,如果相对 URI 的路径为空,则将使用基本 URI 的整个路径:
if (R.path == "") then
T.path = Base.path;
if defined(R.query) then
T.query = R.query;
else
T.query = Base.query;
endif;
并且仅当指定了路径时,才是要与基本路径合并的相对路径:
else
if (R.path starts-with "/") then
T.path = remove_dot_segments(R.path);
else
T.path = merge(Base.path, R.path);
T.path = remove_dot_segments(T.path);
endif;
T.query = R.query;
endif;
但是Java实现总是进行合并,即使路径为空:
String cp = (child.path == null) ? "" : child.path;
if ((cp.length() > 0) && (cp.charAt(0) == '/')) {
// 5.2 (5): Child path is absolute
ru.path = child.path;
} else {
// 5.2 (6): Resolve relative path
ru.path = resolvePath(base.path, cp, base.isAbsolute());
}
如果我的阅读是正确的,为了从RFC伪代码中获取此行为,您可以在查询字符串之前在相对URI中放置一个点作为路径,根据我使用相对URI作为网页中链接的经验,这是我所期望的:
transform(Base="http://example.com/something/more/long", R=".?query")
=> T="http://example.com/something/more/?query"
但是,我希望在网页中,页面上“http://example.com/something/more/long”到“?query”的链接将转到“http://example.com/something/more/long?query”,而不是“http://example.com/something/more/?query” - 换句话说,与RFC一致,但与Java实现不一致。
我对RFC的解读是否正确,而Java方法与它不一致,还是我遗漏了什么?