web-dev-qa-db-fra.com

Ajouter l'URL relative à Java.net.URL

Si j’ai un objet Java.net.URL, pointant vers, disons

http://example.com/myItems ou http://example.com/myItems/

Y at-il un assistant quelque part pour ajouter une URL relative à ceci? Par exemple, ajoutez ./myItemId ou myItemId pour obtenir: http://example.com/myItems/myItemId

28
fulmicoton

URL a un constructeur qui prend une base URL et une spécification String.

Sinon, Java.net.URI adhère plus étroitement aux normes et dispose d'une méthode resolve pour faire la même chose. Créez une URI à partir de votre URL en utilisant URL.toURI .

23
Andrew Duffy

Celui-ci n'a besoin d'aucune bibliothèque ni code supplémentaire et donne le résultat souhaité: 

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

Cela imprime: 

http://petstore.swagger.wordnik.com/api/api-docs
http://petstore.swagger.wordnik.com/api/api-docs/pet

La réponse acceptée ne fonctionne que s'il n'y a pas de chemin après l'hôte (à mon humble avis, la réponse acceptée est fausse)

24

Voici une fonction d'assistance que j'ai écrite à ajouter au chemin de l'URL:

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

J'ai cherché loin pour une réponse à cette question. La seule implémentation que je puisse trouver se trouve dans le SDK Android: Uri.Builder . Je l'ai extrait pour mes propres besoins.

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

This est l'endroit où j'ai trouvé la source.

En conjonction avec Apache URIBuilder , voici comment je l’utilise: builder.setPath(appendSegmentToPath(builder.getPath(), segment));

4
twhitbeck

Vous pouvez utiliser URIBuilder et la méthode URI#normalize pour éviter les doublons / dans l'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
3
herau

MIS À JOUR

Je crois que c'est la solution la plus courte:

URL url1 = new URL("http://domain.com/contextpath");
String relativePath = "/additional/relative/path";
URL concatenatedUrl = new URL(url1.toExternalForm() + relativePath);
1
Galya

Quelques exemples utilisant 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());

Résultat 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());

Résultat 2 -> http://example.com/test/example

1
Marcelo C.

J'ai eu quelques difficultés avec l'encodage des URI. L'ajout ne fonctionnait pas pour moi car il s'agissait d'un contenu: // et il n'aimait pas "/". Cette solution ne suppose aucune requête, ni fragment (nous travaillons après tout avec des chemins):

Code Kotlin:

  val newUri = Uri.parse(myUri.toString() + Uri.encode("/$relPath"))
1
johnml1135

Vous pouvez simplement utiliser la classe URI pour ceci:

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

Notez la barre oblique de fin sur le chemin de base et le format relatif à la base du segment ajouté. Vous pouvez également utiliser la classe URIBuilder à partir du client HTTP Apache:

<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

Concaténez un chemin relatif vers un URI:

Java.net.URI uri = URI.create("https://stackoverflow.com/questions")
Java.net.URI res = uri.resolve(uri.getPath + "/some/path")

res contiendra https://stackoverflow.com/questions/some/path

1
Martin Tapp

Ma solution basée sur la réponse 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;
    }
}

Tester:

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

Pour Android, assurez-vous d'utiliser .appendPath() à partir de Android.net.Uri

0
Roman Gherta