URL/URI Java неправильно разрешает ссылки, начинающиеся с? (точка допроса)
Я пытаюсь определить относительную ссылку, которая начинается со знака вопроса ?
используя Java URL
или же URI
классы.
Пример HTML:
<a href="?test=xyz">Test XYZ</a>
Примеры кода (из Scala REPL):
import java.net._
scala> new URL(new URL("http://abc.com.br/index.php?hello=world"), "?test=xyz").toExternalForm()
res30: String = http://abc.com.br/?test=xyz
scala> (new URI("http://abc.com.br/index.php?hello=world")).resolve("?test=xyz").toString
res31: java.net.URI = http://abc.com.br/?test=xyz
Проблема в том, что браузеры (протестированные в Chrome, Firefox и Safari) вместо этого выводят следующий URL: http://abc.com.br/index.php?hello=world
, Это не отбрасывает путь "index.php". Он просто заменяет часть строки запроса.
И похоже, что браузеры просто следуют спецификации, как описано в /questions/20124848/dejstvitelno-li-ssyilka-href-tolko-s-parametrami-nachinaya-s-voprositelnogo-znaka/20124862#20124862.
Библиотека Jsoup допускает ту же "ошибку", когда мы используем element.absUrl("href")
как это также зависит от Java URL
разрешения.
Так что случилось с Java URL/URI
разрешать относительные пути? Это неправильно / не полностью? Как заставить его вести себя так же, как реализация браузера?
1 ответ
Это будет работать просто отлично:
public static void main(String[] args) throws Exception {
String base = "http://abc.com.br/index.php?hello=world";
String relative = "?test=xyz";
System.out.println(new URL(new URL(base), relative).toExternalForm());
// http://abc.com.br/?test=xyz
System.out.println((new URI(base)).resolve(relative).toString());
// http://abc.com.br/?test=xyz
System.out.println(org.apache.http.client.utils.URIUtils.resolve(new URI(base), relative).toString());
// http://abc.com.br/index.php?test=xyz
}
URIUtils находятся в org.apache.httpcomponents:httpclient версии 4.0 или выше.