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
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
.
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)
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();
}
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));
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
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);
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
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"))
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();
}
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
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());
}
}
Pour Android, assurez-vous d'utiliser .appendPath()
à partir de Android.net.Uri