Добавить относительный URL-адрес в java.net.URL
Если у меня есть объект java.net.URL, указывающий, что можно сказать
http://example.com/myItems
или http://example.com/myItems/
Есть ли какой-нибудь помощник, чтобы добавить к нему какой-то относительный URL?
Например, добавьте ./myItemId
или myItemId
, чтобы получить:
http://example.com/myItems/myItemId
Ответы
Ответ 1
URL
имеет конструктор, который принимает базовый URL
и спецификацию String
.
В качестве альтернативы, java.net.URI
придерживается более строгих стандартов и имеет метод resolve
сделать то же самое. Создайте URI
из вашего URL
используя URL.toURI
.
Ответ 2
Для этого нет необходимости в дополнительных libs или code и дает желаемый результат:
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);
Отпечатки:
http://petstore.swagger.wordnik.com/api/api-docs
http://petstore.swagger.wordnik.com/api/api-docs/pet
Принятый ответ работает только в том случае, если после хоста нет пути (IMHO принятый ответ неверен)
Ответ 3
Вот вспомогательная функция, которую я написал для добавления к 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();
}
Ответ 4
Я искал по всему миру ответ на этот вопрос. Единственная реализация, которую я могу найти, находится в Android SDK: Uri.Builder. Я извлек его для своих целей.
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;
}
Это, где я нашел источник.
В сочетании с Apache URIBuilder, вот как я его использую: builder.setPath(appendSegmentToPath(builder.getPath(), segment));
Ответ 5
Вы можете использовать URIBuilder и метод URI#normalize
чтобы избежать дублирования /
в 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
Ответ 6
ОБНОВЛЕНО
Я считаю, что это кратчайшее решение:
URL url1 = new URL("http://domain.com/contextpath");
String relativePath = "/additional/relative/path";
URL concatenatedUrl = new URL(url1.toExternalForm() + relativePath);
Ответ 7
Некоторые примеры с использованием 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());
Результат 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());
Результат 2 → http://example.com/test/example
Ответ 8
Объединить относительный путь к URI:
java.net.URI uri = URI.create("https://stackoverflow.com/questions")
java.net.URI res = uri.resolve(uri.getPath + "/some/path")
res
будет содержать https://stackoverflow.com/questions/some/path
Ответ 9
Вы можете просто использовать класс URI
для этого:
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
Обратите внимание на косую черту на базовом пути и базовый относительный формат добавляемого сегмента. Вы также можете использовать класс URIBuilder
из 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();
}
Ответ 10
У меня были некоторые трудности с кодировкой URI. Аппендинг не работал для меня, потому что он имел тип содержимого://и ему не нравился символ "/". Это решение не предполагает ни запроса, ни фрагмента (в конце концов, мы работаем с путями):
Код Котлина:
val newUri = Uri.parse(myUri.toString() + Uri.encode("/$relPath"))
Ответ 11
Мое решение на основе ответа 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;
}
}
Тест:
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
Ответ 12
Для android убедитесь, что вы используете .appendPath()
от android.net.Uri
Ответ 13
На Android вы можете использовать android.net.Uri
. Следующее позволяет создать Uri.Builder
из существующего URL как String
а затем добавить:
Uri.parse(baseUrl) // Create Uri from String
.buildUpon() // Creates a "Builder"
.appendEncodedPath("path/to/add")
.build()
Обратите внимание, что appendEncodedPath
не ожидает начала /
и содержит только проверку, заканчивается ли "baseUrl" на единицу, в противном случае он добавляется перед путем.