Java – Convertir cadena en objeto URI válido

Estoy tratando de obtener un objeto java.net.URI de una String . La cadena tiene algunos caracteres que deberán ser reemplazados por sus secuencias de porcentaje de escape. Pero cuando uso URLEncoder para codificar el String con encoding UTF-8, incluso / se reemplazan con sus secuencias de escape.

¿Cómo puedo obtener una URL codificada válida de un objeto String?

http://www.google.com?q=a b da http% 3A% 2F% 2www.google.com … mientras que yo quiero que la salida sea http://www.google.com?q=a% 20b

¿Puede alguien decirme cómo lograr esto?

Estoy tratando de hacer esto en una aplicación de Android. Así que tengo acceso a un número limitado de bibliotecas.

Puede intentar: org.apache.commons.httpclient.util.URIUtil.encodeQuery en el proyecto Apache commons-httpclient

Me gusta esto (ver URIUtil ):

 URIUtil.encodeQuery("http://www.google.com?q=ab") 

se convertirá:

 http://www.google.com?q=a%20b 

Por supuesto, puede hacerlo usted mismo, pero el análisis de URI puede ser bastante complicado …

Android siempre ha tenido la clase Uri como parte del SDK: http://developer.android.com/reference/android/net/Uri.html

Simplemente puede hacer algo como:

 String requestURL = String.format("http://www.example.com/?a=%s&b=%s", Uri.encode("foo bar"), Uri.encode("100% fubar'd")); 

Voy a agregar una sugerencia aquí dirigida a usuarios de Android. Puede hacer esto, lo que evita tener que obtener bibliotecas externas. Además, todas las soluciones de búsqueda / reemplazo de caracteres sugeridas en algunas de las respuestas anteriores son peligrosas y deben evitarse.

Prueba esto:

 String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4"; URL url = new URL(urlStr); URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); url = uri.toURL(); 

Puedes ver que en esta URL en particular, necesito tener esos espacios codificados para que pueda usarlos para una solicitud.

Aprovecha un par de funciones disponibles para ti en las clases de Android. En primer lugar, la clase de URL puede dividir una url en sus componentes adecuados, por lo que no es necesario que realice ningún trabajo de búsqueda / reemplazo de cadenas. En segundo lugar, este enfoque aprovecha la característica de clase URI de escapes adecuados de componentes cuando se construye un URI a través de componentes en lugar de a partir de una sola cadena.

La belleza de este enfoque es que puede tomar cualquier cadena de URL válida y hacer que funcione sin necesidad de ningún conocimiento especial de la misma.

Incluso si se trata de una publicación anterior con una respuesta ya aceptada, publico mi respuesta alternativa porque funciona bien para el presente número y parece que nadie mencionó este método.

Con la biblioteca java.net.URI:

 URI uri = URI.create(URLString); 

Y si desea una cadena con formato de URL correspondiente:

 String validURLString = uri.toASCIIString(); 

A diferencia de muchos otros métodos (por ejemplo, java.net.URLEncoder), este solo reemplaza los caracteres ASCII inseguros (como ç , é …).


En el ejemplo anterior, si URLString es la siguiente String :

 "http://www.domain.com/façon+word" 

el validURLString resultante será:

 "http://www.domain.com/fa%C3%A7on+word" 

que es una URL bien formateada.

Si no te gustan las bibliotecas, ¿qué tal esto?

Tenga en cuenta que no debe usar esta función en toda la URL, sino que debe usar esto en los componentes … por ejemplo, solo el componente “ab”, a medida que construye la URL; de lo contrario, la computadora no sabrá qué caracteres se suponen tener un significado especial y cuáles se supone que tienen un significado literal.

 /** Converts a string into something you can safely insert into a URL. */ public static String encodeURIcomponent(String s) { StringBuilder o = new StringBuilder(); for (char ch : s.toCharArray()) { if (isUnsafe(ch)) { o.append('%'); o.append(toHex(ch / 16)); o.append(toHex(ch % 16)); } else o.append(ch); } return o.toString(); } private static char toHex(int ch) { return (char)(ch < 10 ? '0' + ch : 'A' + ch - 10); } private static boolean isUnsafe(char ch) { if (ch > 128 || ch < 0) return true; return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0; } 

Puede usar los constructores de argumentos múltiples de la clase URI . Desde el URI javadoc:

Los constructores de argumentos múltiples citan caracteres ilegales según lo exigen los componentes en los que aparecen. El carácter de porcentaje (‘%’) siempre es citado por estos constructores. Cualquier otro personaje se conserva.

Entonces si usas

 URI uri = new URI("http", "www.google.com?q=ab"); 

Entonces obtienes http:www.google.com?q=a%20b que no está del todo bien, pero está un poco más cerca.

Si sabe que su cadena no tendrá fragmentos de URL (por ej., http://example.com/page#anchor ), puede usar el siguiente código para obtener lo que desea:

 String s = "http://www.google.com?q=ab"; String[] parts = s.split(":",2); URI uri = new URI(parts[0], parts[1], null); 

Para estar seguro, debería escanear la cadena para # caracteres, pero esto debería comenzar.

Tuve problemas similares para uno de mis proyectos para crear un objeto URI a partir de una cadena. No pude encontrar ninguna solución limpia tampoco. Esto es lo que se me ocurrió:

 public static URI encodeURL(String url) throws MalformedURLException, URISyntaxException { URI uriFormatted = null; URL urlLink = new URL(url); uriFormatted = new URI("http", urlLink.getHost(), urlLink.getPath(), urlLink.getQuery(), urlLink.getRef()); return uriFormatted; } 

Puede usar el siguiente constructor de URI para especificar un puerto si es necesario:

 URI uri = new URI(scheme, userInfo, host, port, path, query, fragment); 

Bueno, traté de usar

 String converted = URLDecoder.decode("toconvert","UTF-8"); 

Espero que esto sea lo que realmente estabas buscando?

El otro día, el blog java.net tuvo una clase que podría haber hecho lo que querías (pero ahora no funciona, así que no puedo verificar).

Este código aquí probablemente podría modificarse para hacer lo que desee:

http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/UriBuilder.java

Aquí está el que estaba pensando en java.net: https://urlencodedquerystring.dev.java.net/

O tal vez podrías usar esta clase:

http://developer.android.com/reference/java/net/URLEncoder.html

Que está presente en Android desde el nivel 1 de la API.

Sin embargo, molestamente trata los espacios especialmente (reemplazándolos con + en lugar de% 20). Para evitar esto simplemente usamos este fragmento:

URLEncoder.encode(value, "UTF-8").replace("+", "%20");

Terminé usando httpclient-4.3.6:

 import org.apache.http.client.utils.URIBuilder; public static void main (String [] args) { URIBuilder uri = new URIBuilder(); uri.setScheme("http") .setHost("www.example.com") .setPath("/somepage.php") .setParameter("username", "Hello Günter") .setParameter("p1", "parameter 1"); System.out.println(uri.toString()); } 

La salida será:

  http://www.example.com/somepage.php?username=Hello+G%C3%BCnter&p1=paramter+1