Mi aplicación independiente Java obtiene una URL (que apunta a un archivo) del usuario y necesito presionarla y descargarla. El problema al que me enfrento es que no puedo codificar la dirección URL HTTP correctamente ...
Ejemplo:
URL: http://search.barnesandnoble.com/booksearch/first book.pdf
java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");
me devuelve:
http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf
Pero lo que quiero es
http://search.barnesandnoble.com/booksearch/first%20book.pdf
(espacio reemplazado por% 20)
Supongo URLEncoder
que no está diseñado para codificar URL HTTP ... El JavaDoc dice "Clase de utilidad para codificación de formulario HTML" ... ¿Hay alguna otra forma de hacer esto?
Respuestas:
La clase java.net.URI puede ayudar; en la documentación de URL que encuentre
Use uno de los constructores con más de un argumento, como:
(el constructor de argumento único de URI NO escapa a caracteres ilegales)
Solo los caracteres ilegales se escapan por el código anterior: NO escapa a los caracteres que no son ASCII (vea el comentario de fatih)
El
toASCIIString
método se puede usar para obtener una Cadena solo con caracteres US-ASCII:Para una URL con una consulta como
http://www.google.com/ig/api?weather=São Paulo
, use la versión de 5 parámetros del constructor:fuente
java.net.URI
: funcionó perfectamente (Java 1.6). Mencionaría el nombre de clase totalmente calificado si no fuera el estándar de Java y el enlace apunta a la documentación dejava.net.URI
. Y, por el comentario de Sudhakar, ¡resolvió el problema sin incluir ninguna "biblioteca de bienes comunes"!Tenga en cuenta que la mayoría de las respuestas anteriores son INCORRECTAS.
La
URLEncoder
clase, a pesar de su nombre, NO es lo que necesita estar aquí. Es desafortunado que Sun haya llamado a esta clase tan molestamente.URLEncoder
está destinado a pasar datos como parámetros, no para codificar la URL en sí.En otras palabras,
"http://search.barnesandnoble.com/booksearch/first book.pdf"
es la URL. Los parámetros serían, por ejemplo"http://search.barnesandnoble.com/booksearch/first book.pdf?parameter1=this¶m2=that"
,. Los parámetros son para lo que usaríasURLEncoder
.Los siguientes dos ejemplos resaltan las diferencias entre los dos.
Lo siguiente produce los parámetros incorrectos, de acuerdo con el estándar HTTP. Tenga en cuenta que el ampersand (&) y plus (+) están codificados incorrectamente.
Lo siguiente producirá los parámetros correctos, con la consulta correctamente codificada. Tenga en cuenta los espacios, los signos y los signos más.
fuente
query = URLEncoder.encode(key) + "=" + URLEncoder.encode(value)
. Los documentos simplemente dicen que "se cita cualquier carácter que no sea un carácter URI legal".Agregaré una sugerencia aquí dirigida a usuarios de Android. Puede hacer esto para evitar 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:
Puede ver que en esta URL en particular, necesito tener esos espacios codificados para poder usarlo para una solicitud.
Esto aprovecha algunas funciones disponibles en las clases de Android. Primero, 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 escapar componentes correctamente cuando construye un URI a través de componentes en lugar de hacerlo desde 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 usted mismo.
fuente
#
.Una solución que desarrollé y mucho más estable que cualquier otra:
fuente
String utf8Input = new String(Charset.forName("UTF-8").encode(input).array());
(tomada de aquí )Si tiene una URL, puede pasar url.toString () a este método. Primero decodifique, para evitar la doble codificación (por ejemplo, codificar un espacio da como resultado% 20 y codificar un signo de porcentaje da como resultado% 25, por lo que la codificación doble convertirá un espacio en% 2520). Luego, use el URI como se explicó anteriormente, agregando todas las partes de la URL (para que no suelte los parámetros de consulta).
fuente
Sí, la codificación de URL codificará esa cadena para que se pase correctamente en una URL a un destino final. Por ejemplo, no podría tener http://stackoverflow.com?url=http://yyy.com . La codificación Url del parámetro arreglaría ese valor del parámetro.
Entonces tengo dos opciones para ti:
¿Tiene acceso a la ruta separada del dominio? Si es así, puede simplemente codificar UrlEncode la ruta. Sin embargo, si este no es el caso, entonces la opción 2 puede ser para usted.
Obtenga commons-httpclient-3.1. Esto tiene una clase URIUtil:
System.out.println (URIUtil.encodePath (" http://example.com/x y", "ISO-8859-1"));
Esto generará exactamente lo que está buscando, ya que solo codificará la parte de ruta del URI.
Para su información, necesitará el códec commons y el registro de commons para que este método funcione en tiempo de ejecución.
fuente
URIUtil
soluciónNitpicking: una cadena que contiene un espacio en blanco por definición no es un URI Entonces, lo que está buscando es un código que implemente el escape de URI definido en la Sección 2.1 de RFC 3986 .
fuente
Desafortunadamente,
org.apache.commons.httpclient.util.URIUtil
está en desuso y lareplacement org.apache.commons.codec.net.URLCodec
codificación es adecuada para publicaciones de formularios, no en URL reales. Así que tuve que escribir mi propia función, que tiene un solo componente (no es adecuado para cadenas de consulta completas que tienen? Y & 's)fuente
URLEncoding puede codificar URL HTTP muy bien, como desafortunadamente has descubierto. La cadena que ingresó , " http://search.barnesandnoble.com/booksearch/first book.pdf", se codificó correcta y completamente en un formulario codificado en URL. Podrías pasar toda esa cadena larga de gobbledigook que obtuviste como parámetro en una URL, y podría decodificarse de nuevo exactamente en la cadena que ingresaste.
Parece que quiere hacer algo un poco diferente a pasar toda la URL como parámetro. Por lo que deduzco, está intentando crear una URL de búsqueda que se vea como " http://search.barnesandnoble.com/booksearch/whateverTheUserPassesIn ". Lo único que necesita codificar es el bit "whateverTheUserPassesIn", por lo que quizás todo lo que necesita hacer es algo como esto:
Eso debería producir algo más válido para usted.
fuente
Si alguien no quiere agregar una dependencia a su proyecto, estas funciones pueden ser útiles.
Pasamos la parte 'ruta' de nuestra URL aquí. Probablemente no desee pasar la URL completa como parámetro (las cadenas de consulta necesitan diferentes escapes, etc.).
Y pruebas:
fuente
Todavía hay un problema si tienes un "/" codificado (% 2F) en tu URL.
RFC 3986 - La sección 2.2 dice: "Si los datos para un componente URI entraran en conflicto con el propósito de un carácter reservado como delimitador, entonces los datos en conflicto deben codificarse en porcentaje antes de que se forme el URI". (RFC 3986 - Sección 2.2)
Pero hay un problema con Tomcat:
Entonces, si tiene una URL con el carácter% 2F, Tomcat devuelve: "400 URI no válido: noSlash"
Puede cambiar la corrección de errores en el script de inicio de Tomcat:
fuente
Leí las respuestas anteriores para escribir mi propio método porque no podía hacer que algo funcionara correctamente usando la solución de las respuestas anteriores, me parece bien, pero si puede encontrar una URL que no funcione con esto, hágamelo saber.
fuente
Estoy de acuerdo con Matt De hecho, nunca lo he visto bien explicado en los tutoriales, pero una cuestión es cómo codificar la ruta de la URL, y una muy diferente es cómo codificar los parámetros que se agregan a la URL (la parte de la consulta, detrás de "? "símbolo). Usan una codificación similar, pero no la misma.
Especialmente para la codificación del espacio en blanco. La ruta URL necesita que se codifique como% 20, mientras que la parte de la consulta permite% 20 y también el signo "+". La mejor idea es probarlo nosotros mismos contra nuestro servidor web, utilizando un navegador web.
Para ambos casos, SIEMPRE codificaría COMPONENTE POR COMPONENTE , nunca la cadena completa. De hecho, URLEncoder permite eso para la parte de consulta. Para la parte de ruta, puede usar el URI de clase, aunque en este caso solicita la cadena completa, no un solo componente.
De todos modos, creo que la mejor manera de evitar estos problemas es usar un diseño personal no conflictivo. ¿Cómo? Por ejemplo, nunca nombraría directorios o parámetros usando otros caracteres que no sean aZ, AZ, 0-9 y _. De esa manera, la única necesidad es codificar el valor de cada parámetro, ya que puede provenir de una entrada del usuario y los caracteres utilizados son desconocidos.
fuente
Quizás pueda probar UriUtils en org.springframework.web.util
fuente
También puedes usar
GUAVA
y path escape:UrlEscapers.urlFragmentEscaper().escape(relativePath)
fuente
Además de la respuesta de Carlos Heuberger: si se necesita un valor diferente al predeterminado (80), se debe usar el constructor de 7 parámetros:
fuente
Tomé el contenido anterior y lo cambié un poco. Primero me gusta la lógica positiva, y pensé que un HashSet podría ofrecer un mejor rendimiento que otras opciones, como buscar en una Cadena. Aunque, no estoy seguro de si la penalización de autoboxing vale la pena, pero si el compilador se optimiza para caracteres ASCII, entonces el costo del boxeo será bajo.
fuente
Utilice la siguiente solución estándar de Java (pasa alrededor de 100 de los casos de prueba proporcionados por Web Plattform Tests ):
0. Pruebe si la URL ya está codificada .
1. Dividir URL en partes estructurales. Úselo
java.net.URL
para ello.2. ¡ Codifique cada parte estructural correctamente!
3. Utilice
IDN.toASCII(putDomainNameHere)
para codificar Punycode el nombre del host!4. Utilícelo
java.net.URI.toASCIIString()
para codificar en porcentaje, unicode codificado con NFC - (¡mejor sería NFKC!).Encuentre más aquí: https://stackoverflow.com/a/49796882/1485527
fuente
He creado un nuevo proyecto para ayudar a construir URL HTTP. La biblioteca codificará automáticamente los segmentos de ruta de codificación URL y los parámetros de consulta.
Puede ver la fuente y descargar un binario en https://github.com/Widen/urlbuilder
La URL de ejemplo en esta pregunta:
produce
http://search.barnesandnoble.com/booksearch/first%20book.pdf
fuente
Yo tuve el mismo problema. Solucionó esto al deshacer:
Codifica la cadena pero omite ":" y "/".
fuente
yo uso esto
agrega esta dependencia
fuente
Desarrollo una biblioteca que sirve para este propósito: galimatias . Analiza la URL de la misma manera que los navegadores web. Es decir, si una URL funciona en un navegador, galimatias la analizará correctamente .
En este caso:
Le dará:
http://search.barnesandnoble.com/booksearch/first%20book.pdf
. Por supuesto, este es el caso más simple, pero funcionará con cualquier cosa, mucho más allájava.net.URI
.Puede consultarlo en: https://github.com/smola/galimatias
fuente
Puedes usar una función como esta. Complete y modifíquelo según sus necesidades:
Ejemplo de uso:
El resultado es: http://www.growup.com/folder/int%C3%A9rieur-%C3%A0_vendre?o=4
fuente
String url = "" http://search.barnesandnoble.com/booksearch/ ;
Supongo que esto será constante y que solo el nombre de archivo cambia dinámicamente
String filename; // obtener el nombre del archivo
Cadena urlEnc = url + fileName.replace ("", "% 20");
fuente
Qué tal si:
public String UrlEncode (String in_) {
}
fuente