Vorausgesetzt, ich habe ein Java.net.URL-Objekt, das darauf hinweist, sagen wir
http://example.com/myItems
oder http://example.com/myItems/
Gibt es irgendwo einen Helfer, an den eine relative URL angehängt wird? Fügen Sie beispielsweise ./myItemId
oder myItemId
hinzu, um Folgendes zu erhalten: http://example.com/myItems/myItemId
URL
hat einen Konstruktor , der eine Basis URL
und eine String
spezifiziert.
Alternativ hält sich Java.net.URI
enger an die Standards und verwendet eine resolve
-Methode, um dasselbe zu tun. Erstellen Sie eine URI
aus Ihrer URL
mit URL.toURI
.
Dieser benötigt keine zusätzlichen Bibliotheken oder Codes und liefert das gewünschte Ergebnis:
URL url1 = new URL("http://petstore.swagger.wordnik.com/api/api-docs");
URL url2 = new URL(url1.getProtocol(), url1.getHost(), url1.getPort(), url1.getFile() + "/pet", null);
System.out.println(url1);
System.out.println(url2);
Dies druckt:
http://petstore.swagger.wordnik.com/api/api-docs
http://petstore.swagger.wordnik.com/api/api-docs/pet
Die akzeptierte Antwort funktioniert nur, wenn nach dem Host kein Pfad vorhanden ist (IMHO ist die akzeptierte Antwort falsch)
Hier ist eine Hilfsfunktion, die ich geschrieben habe, um den URL-Pfad hinzuzufügen:
public static URL concatenate(URL baseUrl, String extraPath) throws URISyntaxException,
MalformedURLException {
URI uri = baseUrl.toURI();
String newPath = uri.getPath() + '/' + extraPath;
URI newUri = uri.resolve(newPath);
return newUri.toURL();
}
Ich habe weit und breit 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.
private String appendSegmentToPath(String path, String segment) {
if (path == null || path.isEmpty()) {
return "/" + segment;
}
if (path.charAt(path.length() - 1) == '/') {
return path + segment;
}
return path + "/" + segment;
}
Hier habe ich die Quelle gefunden.
In Verbindung mit Apache URIBuilder verwende ich es so: builder.setPath(appendSegmentToPath(builder.getPath(), segment));
Sie können URIBuilder und die Methode URI#normalize
verwenden, um doppelten /
im URI zu vermeiden:
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
AKTUALISIERTE
Ich glaube, das ist die kürzeste Lösung:
URL url1 = new URL("http://domain.com/contextpath");
String relativePath = "/additional/relative/path";
URL concatenatedUrl = new URL(url1.toExternalForm() + relativePath);
Unter Android können Sie Android.net.Uri
verwenden. Im Folgenden können Sie einen Uri.Builder
aus einer vorhandenen URL als String
und erstellen dann anhängen:
Uri.parse(baseUrl) // Create Uri from String
.buildUpon() // Creates a "Builder"
.appendEncodedPath("path/to/add")
.build()
Beachten Sie, dass appendEncodedPath
kein führendes /
erwartet und nur eine Prüfung enthält, ob die "baseUrl" mit eins endet, andernfalls wird eine vor dem Pfad hinzugefügt.
Einige Beispiele mit dem Apache URIBuilder http://hc.Apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/Apache/http/client/utils/URIBuilder.html :
Ex1:
String url = "http://example.com/test";
URIBuilder builder = new URIBuilder(url);
builder.setPath((builder.getPath() + "/example").replaceAll("//+", "/"));
System.out.println("Result 1 -> " + builder.toString());
Ergebnis 1 -> http://example.com/test/example
Ex2:
String url = "http://example.com/test";
URIBuilder builder = new URIBuilder(url);
builder.setPath((builder.getPath() + "///example").replaceAll("//+", "/"));
System.out.println("Result 2 -> " + builder.toString());
Ergebnis 2 -> http://example.com/test/example
Ich hatte einige Schwierigkeiten mit der Kodierung von URIs. Das Anhängen funktionierte nicht für mich, weil es einen Typ mit Inhalt: // hatte und das "/" nicht mochte. Diese Lösung setzt keine Abfrage oder Fragmentierung voraus (wir arbeiten schließlich mit Pfaden):
Kotlin-Code:
val newUri = Uri.parse(myUri.toString() + Uri.encode("/$relPath"))
Sie können dazu einfach die URI
-Klasse verwenden:
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 nachstehenden Schrägstrich im Basispfad und das basenrelative Format des angehängten Segments. Sie können auch die URIBuilder
-Klasse vom Apache HTTP-Client verwenden:
<dependency>
<groupId>org.Apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
...
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() + "/").resolve("./" + path).getPath());
return builder.build();
}
Verketten Sie einen relativen Pfad zu einem URI:
Java.net.URI uri = URI.create("https://stackoverflow.com/questions")
Java.net.URI res = uri.resolve(uri.getPath + "/some/path")
res
enthält https://stackoverflow.com/questions/some/path
Meine Lösung basiert auf der Antwort von twhitbeck:
import Java.net.URI;
import Java.net.URISyntaxException;
public class URIBuilder extends org.Apache.http.client.utils.URIBuilder {
public URIBuilder() {
}
public URIBuilder(String string) throws URISyntaxException {
super(string);
}
public URIBuilder(URI uri) {
super(uri);
}
public org.Apache.http.client.utils.URIBuilder addPath(String subPath) {
if (subPath == null || subPath.isEmpty() || "/".equals(subPath)) {
return this;
}
return setPath(appendSegmentToPath(getPath(), subPath));
}
private String appendSegmentToPath(String path, String segment) {
if (path == null || path.isEmpty()) {
path = "/";
}
if (path.charAt(path.length() - 1) == '/' || segment.startsWith("/")) {
return path + segment;
}
return path + "/" + segment;
}
}
Prüfung:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class URIBuilderTest {
@Test
public void testAddPath() throws Exception {
String url = "http://example.com/test";
String expected = "http://example.com/test/example";
URIBuilder builder = new URIBuilder(url);
builder.addPath("/example");
assertEquals(expected, builder.toString());
builder = new URIBuilder(url);
builder.addPath("example");
assertEquals(expected, builder.toString());
builder.addPath("");
builder.addPath(null);
assertEquals(expected, builder.toString());
url = "http://example.com";
expected = "http://example.com/example";
builder = new URIBuilder(url);
builder.addPath("/");
assertEquals(url, builder.toString());
builder.addPath("/example");
assertEquals(expected, builder.toString());
}
}
Für Android verwenden Sie .appendPath()
aus Android.net.Uri
.