webentwicklung-frage-antwort-db.com.de

Relative URL an Java.net.URL anhängen

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

28
fulmicoton

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 .

23
Andrew Duffy

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)

24

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();
}
5
Andrew Shepherd

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));

4
twhitbeck

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
3
herau

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);
1
Galya

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.

1
sunadorer

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

1
Marcelo C.

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"))
1
johnml1135

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();
}
1
Scott Babcock

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

1
Martin Tapp

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());
    }
}

Gist: https://Gist.github.com/enginer/230e2dc2f1d213a825d5

0
Sllouyssgort

Für Android verwenden Sie .appendPath() aus Android.net.Uri.

0
Roman Gherta