Vorausgesetzt, ich habe ein java.net.URL-Objekt, das auf sagen wir mal zeigt
http://example.com/myItems oder http://example.com/myItems/
Gibt es irgendwo einen Helfer, um eine relative URL daran anzuhängen? Zum Beispiel anhängen ./myItemId oder myItemId zu bekommen : http://example.com/myItems/myItemId
mögliches Duplikat von Erstellen einer absoluten URL aus einer relativen URL im Java-Servlet
– Don Roby
21. September 2011 um 10:15 Uhr
Es scheint, dass es keine einfache Lösung gibt. Entweder die URL oder die URI-Klasse unterstützt dies nicht. Auch Apache HttpClient unterstützt dies nicht.
– Sri
29. Juli 2017 um 2:43
Andrew Duffy
URL hat ein Konstrukteur Das braucht eine Basis URL und ein String spez.
Alternative, java.net.URI hält sich stärker an die Standards und verfügt über eine resolve Methode, um dasselbe zu tun. Ein … kreieren URI von deiner URL verwenden URL.toURI.
Zum Nutzen anderer: Die erste URL-Konstruktormethode funktionierte nicht ganz so, wie ich es erwartet hatte (rtfm, nicht wahr?). Es wird nur der Nicht-Pfad-Teil der Basis-URL verwendet.
– Jasper Blues
7. Januar 2016 um 5:31
@user2585038: Der zweite Parameter darf nicht mit einem Schrägstrich beginnen. Der Schrägstrich gibt einen „absoluten“ Link an, daher wird der Pfad von URL1 verworfen.
– Harsel
21. Juni 2016 um 8:40 Uhr
Die URI-Auflösung funktioniert hier eigentlich nur aus Versehen. siehe die Antwort von @Christoph Henkelmann von unten
– Ittai
12. Okt. 2016 um 20:17 Uhr
Wie @user2585038 erwähnte, berücksichtigt diese Antwort Abschnitt 5.2 (6a) nicht RFC2396 Darin heißt es: „Alle bis auf das letzte Segment der Pfadkomponente des Basis-URI werden in den Puffer kopiert. Mit anderen Worten: Alle Zeichen nach dem letzten (ganz rechts stehenden) Schrägstrich, falls vorhanden, werden ausgeschlossen.“ Diese IMO macht die URI-Auflösung in den meisten Fällen, einschließlich der des OP, unbrauchbar.
– Steinybot
23. August 2017 um 22:48
Christoph Henkelmann
Dieser benötigt keine zusätzlichen Bibliotheken oder Code und liefert das gewünschte Ergebnis:
@MartinSenne Gut gesehen, ich habe das Beispiel angepasst.
– Christoph Henkelmann
27. Mai 2020 um 14:57 Uhr
Sie können einfach das verwenden URI Klasse dafür:
import java.net.URI;
import org.apache.http.client.utils.URIBuilder;
URI uri = URI.create("http://example.com/basepath/");
URI uri2 = uri.resolve("./relative");
// => http://example.com/basepath/relative
Beachten Sie den abschließenden Schrägstrich im Basispfad und das basisrelative Format des Segments, das angehängt wird. Sie können auch die verwenden URIBuilder Klasse vom Apache HTTP-Client:
import java.net.URI;
import org.apache.http.client.utils.URIBuilder;
URI uri = URI.create("http://example.com/basepath");
URI uri2 = appendPath(uri, "relative");
// => http://example.com/basepath/relative
public URI appendPath(URI uri, String path) {
URIBuilder builder = new URIBuilder(uri);
builder.setPath(URI.create(builder.getPath() + "https://stackoverflow.com/").resolve("./" + path).getPath());
return builder.build();
}
Das Ergebnis des ersten Codebits ist nichthttp://example.com/basepath/relativeAber http://example.com/relativewas den ersten Teil dieser Antwort leider falsch macht.
Ich kann nicht glauben, wie böse URI.resolve() Es ist wirklich voller fieser Randfälle.
new URI("http://localhost:80").resolve("foo") => "http://localhost:80foo"
new URI("http://localhost:80").resolve("//foo") => "http://foo"
new URI("http://localhost:80").resolve(".//foo") => "http://foo"
Die sauberste Lösung, die ich je gesehen habe und die diese Randfälle auf vorhersehbare Weise behandelt, ist:
Hier ist eine Hilfsfunktion, die ich geschrieben habe, um sie dem URL-Pfad hinzuzufügen:
public static URL concatenate(URL baseUrl, String extraPath) throws URISyntaxException,
MalformedURLException {
URI uri = baseUrl.toURI();
String newPath = uri.getPath() + "https://stackoverflow.com/" + extraPath;
URI newUri = uri.resolve(newPath);
return newUri.toURL();
}
Wenn baseUrl endet mit a / oder extraPath beginnt mit a / Du wirst es wiederholt haben / in der finalen URL. Sie sollten a hinzufügen .normalize() vor dem letzten toURL().
– Simão Martins
19. Mai 2017 um 14:42 Uhr
Dies funktioniert nicht für eine lokale Datei-URL, die mit file:// beginnen sollte.
– Sundar Rajan
2. Juli 2018 um 6:38
Wenn baseUrl.getPath() Ist "/" Dadurch wird der Host geändert!!! URI("http://localhost:80").resolve("//foo") => "http://foo" Im Folgenden zeige ich, wie man diese angeht.
– ja
2. Dezember 2021 um 11:56 Uhr
Sie können verwenden URIBuilder und die Methode URI#normalize um Duplikate zu vermeiden / in der URI:
URIBuilder uriBuilder = new URIBuilder("http://example.com/test");
URI uri = uriBuilder.setPath(uriBuilder.getPath() + "/path/to/add")
.build()
.normalize();
// expected : http://example.com/test/path/to/add
Wenn baseUrl endet mit a / oder extraPath beginnt mit a / Du wirst es wiederholt haben / in der finalen URL. Sie sollten a hinzufügen .normalize() vor dem letzten toURL().
– Simão Martins
19. Mai 2017 um 14:42 Uhr
Dies funktioniert nicht für eine lokale Datei-URL, die mit file:// beginnen sollte.
– Sundar Rajan
2. Juli 2018 um 6:38
Wenn baseUrl.getPath() Ist "/" Dadurch wird der Host geändert!!! URI("http://localhost:80").resolve("//foo") => "http://foo" Im Folgenden zeige ich, wie man diese angeht.
– ja
2. Dezember 2021 um 11:56 Uhr
twhitbeck
Ich habe lange nach einer Antwort auf diese Frage gesucht. Die einzige Implementierung, die ich finden kann, ist im Android SDK: Uri.Builder. Ich habe es für meine eigenen Zwecke extrahiert.
mögliches Duplikat von Erstellen einer absoluten URL aus einer relativen URL im Java-Servlet
– Don Roby
21. September 2011 um 10:15 Uhr
Es scheint, dass es keine einfache Lösung gibt. Entweder die URL oder die URI-Klasse unterstützt dies nicht. Auch Apache HttpClient unterstützt dies nicht.
– Sri
29. Juli 2017 um 2:43