fulmicotón
Siempre que tenga un objeto java.net.URL, apuntando a digamos
http://example.com/myItems
o http://example.com/myItems/
¿Hay algún ayudante en algún lugar para agregar alguna URL relativa a esto? Por ejemplo agregar ./myItemId
o myItemId
Llegar :
http://example.com/myItems/myItemId
andres duffy
URL
tiene un constructor que toma una base URL
y un String
Especificaciones.
Alternativamente, java.net.URI
se adhiere más estrechamente a los estándares, y tiene un resolve
método para hacer lo mismo. Crear un URI
de tu URL
usando URL.toURI
.
-
“URL tiene un constructor que toma una URL base y una especificación de cadena”. – No es útil. URL url1 = nueva URL (“petstore.swagger.wordnik.com/api/api-docs”); URL url2 = nueva URL (url1, “/mascota”); System.out.println(url2.toString()) te da: petstore.swagger.wordnik.com/petno petstore.swagger.wordnik.com/api/api-docs/pet
– usuario2585038
14/10/2013 a las 17:25
-
En beneficio de los demás: el primer método constructor de URL no funcionó de la manera que esperaba (rtfm, ¿eh?). Solo se utiliza la parte que no es de ruta de la baseURL.
– Blues de Jasper
7 de enero de 2016 a las 5:31
-
@user2585038: El segundo parámetro no debe comenzar con una barra inclinada. La barra inclinada indica un enlace “absoluto”, por lo que se descarta la ruta de url1.
– arsel
21 de junio de 2016 a las 8:40
-
La resolución de URI en realidad solo funciona por error aquí. vea la respuesta de @Christoph Henkelmann desde abajo
– Ittai
12/10/2016 a las 20:17
-
Como mencionó @user2585038, esta respuesta no tiene en cuenta la sección 5.2 (6a) de RFC2396 que dice: “Todo menos el último segmento del componente de ruta del URI base se copia en el búfer. En otras palabras, cualquier carácter después del último carácter de barra (más a la derecha), si lo hay, se excluye”. Este IMO hace que la resolución de URI sea inutilizable en la mayoría de los casos, incluido el del OP.
– steinybot
23 de agosto de 2017 a las 22:48
Christoph Henkelmann
Este no necesita bibliotecas ni código adicionales y da el resultado deseado:
//import java.net.URL;
URL url1 = new URL("http://petstore.swagger.wordnik.com/api/api-docs?foo=1&bar=baz");
URL url2 = new URL(url1.getProtocol(), url1.getHost(), url1.getPort(), url1.getPath() + "/pet" + "?" + url1.getQuery(), null);
System.out.println(url1);
System.out.println(url2);
Esto imprime:
http://petstore.swagger.wordnik.com/api/api-docs?foo=1&bar=baz
http://petstore.swagger.wordnik.com/api/api-docs/pet?foo=1&bar=baz
La respuesta aceptada solo funciona si no hay una ruta después del host (en mi humilde opinión, la respuesta aceptada es incorrecta)
-
MalformedUrlException
¿Por qué no lanzan una excepción sin marcar? :'(– gkiko
9 de agosto de 2016 a las 9:03
-
Sí, eso apesta… y es inconsistente: el análisis de números arroja excepciones no verificadas ^^
–Christoph Henkelmann
11 de agosto de 2016 a las 14:49
-
Esta solución no maneja barras inclinadas finales. La pregunta proporciona dos ejemplos.
– rrhrg
2 de agosto de 2018 a las 17:08
-
url1.getFile().endsWith("/") ? url1.getFile() + "pet" : url1.getFile() + "/pet"
?–Christoph Henkelmann
7 de noviembre de 2018 a las 15:01
-
@MartinSenne Bien visto, ajusté el ejemplo.
–Christoph Henkelmann
27 de mayo de 2020 a las 14:57
Solo puedes usar el URI
clase para esto:
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
Tenga en cuenta la barra inclinada final en la ruta base y el formato relativo a la base del segmento que se está agregando. También puede utilizar el URIBuilder
clase del cliente Apache HTTP:
<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() + "https://stackoverflow.com/").resolve("./" + path).getPath());
return builder.build();
}
-
El resultado del primer bit de código es no
http://example.com/basepath/relative
perohttp://example.com/relative
desafortunadamente haciendo que la primera parte de esta respuesta sea incorrecta.– Luciano
14 oct 2019 a las 8:14
-
En realidad, la primera parte de la respuesta es correcta; funciona si no se proporciona el ./ y si hay más de un / en el primer URI. P.EJ x.com:300/z/y/f.txt/////// ~~~ x.com:300/z/y/f.txt/zzccvr.tyt
– Ironluca
5 de marzo de 2020 a las 10:36
iain
No puedo creer lo desagradable URI.resolve()
realmente está lleno de casos extremos desagradables.
new URI("http://localhost:80").resolve("foo") => "http://localhost:80foo"
new URI("http://localhost:80").resolve("//foo") => "http://foo"
new URI("http://localhost:80").resolve(".//foo") => "http://foo"
La solución más ordenada que he visto que maneja estos casos extremos de manera predecible es:
URI addPath(URI uri, String path) {
String newPath;
if (path.startsWith("/")) newPath = path.replaceAll("//+", "/");
else if (uri.getPath().endsWith("/")) newPath = uri.getPath() + path.replaceAll("//+", "/");
else newPath = uri.getPath() + "/" + path.replaceAll("//+", "/");
return uri.resolve(newPath).normalize();
}
Resultados:
jshell> addPath(new URI("http://localhost"), "sub/path")
$3 ==> http://localhost/sub/path
jshell> addPath(new URI("http://localhost/"), "sub/path")
$4 ==> http://localhost/sub/path
jshell> addPath(new URI("http://localhost/"), "/sub/path")
$5 ==> http://localhost/sub/path
jshell> addPath(new URI("http://localhost/random-path"), "/sub/path")
$6 ==> http://localhost/sub/path
jshell> addPath(new URI("http://localhost/random-path"), "./sub/path")
$7 ==> http://localhost/random-path/sub/path
jshell> addPath(new URI("http://localhost/random-path"), "../sub/path")
$8 ==> http://localhost/sub/path
jshell> addPath(new URI("http://localhost"), "../sub/path")
$9 ==> http://localhost/../sub/path
jshell> addPath(new URI("http://localhost/"), "//sub/path")
$10 ==> http://localhost/sub/path
jshell> addPath(new URI("http://localhost/"), "//sub/./path")
$11 ==> http://localhost/sub/path
Aquí hay una función de ayuda que he escrito para agregar a la ruta de la URL:
public static URL concatenate(URL baseUrl, String extraPath) throws URISyntaxException,
MalformedURLException {
URI uri = baseUrl.toURI();
String newPath = uri.getPath() + "https://stackoverflow.com/" + extraPath;
URI newUri = uri.resolve(newPath);
return newUri.toURL();
}
-
Si
baseUrl
termina con un/
oextraPath
comienza con un/
habrás repetido/
en la URL final. Deberías agregar un.normalize()
antes del ultimotoURL()
.– Simão Martins
19 mayo 2017 a las 14:42
-
Esto no funciona para una URL de archivo local que debería comenzar con file://
-Sundar Rajan
2 de julio de 2018 a las 6:38
-
si
baseUrl.getPath()
es"/"
¡¡¡esto modificará el anfitrión!!!URI("http://localhost:80").resolve("//foo")
=>"http://foo"
Muestro cómo abordarlos a continuación.– iain
2 de diciembre de 2021 a las 11:56
Puedes usar URIBuilder y el metodo URI#normalize
para evitar la duplicación /
en la 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
-
Si
baseUrl
termina con un/
oextraPath
comienza con un/
habrás repetido/
en la URL final. Deberías agregar un.normalize()
antes del ultimotoURL()
.– Simão Martins
19 mayo 2017 a las 14:42
-
Esto no funciona para una URL de archivo local que debería comenzar con file://
-Sundar Rajan
2 de julio de 2018 a las 6:38
-
si
baseUrl.getPath()
es"/"
¡¡¡esto modificará el host!!!URI("http://localhost:80").resolve("//foo")
=>"http://foo"
Muestro cómo abordarlos a continuación.– iain
2 de diciembre de 2021 a las 11:56
twitbeck
He buscado por todas partes una respuesta a esta pregunta. La única implementación que puedo encontrar está en el SDK de Android: Uri.Constructor. Lo he extraído para mis propios fines.
private String appendSegmentToPath(String path, String segment) {
if (path == null || path.isEmpty()) {
return "https://stackoverflow.com/" + segment;
}
if (path.charAt(path.length() - 1) == "https://stackoverflow.com/") {
return path + segment;
}
return path + "https://stackoverflow.com/" + segment;
}
Este es donde encontré la fuente.
En conjunto con Apache URIBuilderasí es como lo estoy usando: builder.setPath(appendSegmentToPath(builder.getPath(), segment));
-
Esto se puede usar de la misma manera usando UriBuilder de jersey client/ docs.oracle.com/javaee/7/api/javax/ws/rs/core/UriBuilder.html
– Opcional
18 de abril de 2017 a las 6:34
posible duplicado de Creación de una URL absoluta a partir de una URL relativa en el servlet de Java
– Don Roby
21 de septiembre de 2011 a las 10:15
Parece que no hay una solución sencilla. La clase URL o URI no admite esto. Apache HttpClient tampoco tiene soporte para esto.
– Sri
29 de julio de 2017 a las 2:43