Usted está poniendo en primer lugar la (ya se escape) cadena en la clase URL
. Eso no escapa nada. Luego está sacando secciones del URL
, que las devuelve sin ningún procesamiento posterior (por lo tanto, aún se han escapado porque se habían escapado cuando las insertó). Finalmente, está colocando las secciones en la clase URI
, usando el multi-argument constructor. Este constructor se especifica como codificación de los componentes de URI usando porcentajes.
Por lo tanto, es en este paso final que, por ejemplo, ":
" se convierte en "%3A
" (bueno) y "%3A
" se convierte en "%253A
" (malo). Dado que está colocando URL que ya están codificadas *, no desea volver a codificarlas. Por favor, el single-argument constructor de URI
es tu amigo. No escapa a nada, y requiere que pase una cadena antes de escapar. Por lo tanto, no es necesario en absoluto URL
:
mUrl = "A string url is already percent-encoded for use in a new HttpGet()";
URI uri = new URI(mUrl);
* El único problema es que si sus URL a veces no son codificados por ciento, ya veces son. Entonces tienes un problema mayor. Debe decidir si su programa está comenzando con una URL que siempre está codificada, o una que necesita ser codificada.
Tenga en cuenta que no existe tal cosa como una URL completa que no está codificada en porcentajes. Por ejemplo, no puede tomar la URL completa "http://example.com/bob&co
" y de alguna manera convertirla en la URL codificada correctamente "http://example.com/bob%26co
": ¿cómo puede saber la diferencia entre la sintaxis (que no se debe escapar) y los caracteres (que debería)? Esta es la razón por la que la forma de argumento único de URI
requiere que las cadenas ya estén escapadas. Si usted tiene cadenas sin escape, es necesario que ellos por ciento a codificar antes de insertarlos en la sintaxis URL completa, y eso es lo que el constructor de múltiples argumento de URI
le ayuda a hacerlo.
Edit: Eché de menos el hecho de que el código original descarta el fragmento.Si desea eliminar el fragmento (o cualquier otra parte) de la URL, puede construir el URI
como se indicó anteriormente, luego extraer todas las partes según sea necesario (serán decodificadas en cadenas normales), y luego volver a pasarlas a el constructor URI
multi-argumento (donde estarán re-codificada como componentes URI):
uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
uri.getPath(), uri.getQuery(), null) // Remove fragment
Eso tiene sentido, gracias por la redacción. Las URL se extraen del código html, así que supongo que tendrían que estar codificadas entonces? Una de las razones por las que estaba usando el URL y el constructor de argumentos múltiples fue porque necesitaba eliminar el fragmento (si lo hubiera) del URI. ¿Hay alguna manera de que pueda hacer esto sin forzar la doble codificación? Algo como String urlMinusFragment = url.getProtocol() + ": //" + url.getAuthority() + url.getPath() + "?" + url.getQuery(); ¿Estás seguro de hacer? Entonces podría lanzar esa cadena en el nuevo constructor de URI (cadena). Gracias de nuevo. – cottonBallPaws
Si está extrayendo URL de, por ejemplo, la propiedad 'href' en HTML, entonces siempre deben codificarse correctamente (si no lo están, el HTML no es válido, por lo que podría tratarlo como un error). La técnica para eliminar el fragmento parece correcta, pero está construyendo manualmente una URL (para la cual hay una biblioteca). Usaría la clase URI. Al igual que la URL, URI tiene captadores de componentes, pero devuelve cadenas * decodificadas * que son seguras para volver a colocar en el URI. Así 'URI (uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), null)' debería funcionar. – mgiuca
brillant, funciona a la perfección. Gracias – cottonBallPaws