Я считаю, что определение и реализация метода Java URI.resolve несовместимо с RFC 3986, раздел 5.2.2. Я понимаю, что Java API определяет, как работает этот метод, и если он был изменен, теперь он нарушит существующие приложения, но мой вопрос таков: Может ли кто-нибудь подтвердить мое понимание, что этот метод несовместим с RFC 3986?
Я использую пример из этого вопроса: java.net.URI разрешает только строку запроса, которую я буду копировать здесь:
Я пытаюсь создать URI с помощью JDK java.net.URI. Я хочу добавить к абсолютному объекту URI, запросу (в String). В примере:
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" на "запрос" будет перейдите к разделу http://example.com/something/more/long?query", а не " http://example.com/something/more/?query "- другими словами, в соответствии с RFC, но не с реализацией Java.
Я читаю RFC правильно, и метод Java несовместим с ним, или я что-то не хватает?