Utilizando Java, quiero quitar el identificador de fragmento y realizar una normalización simple (por ejemplo, esquemas en minúscula, hosts) de un conjunto diverso de URI. Los URI de entrada y salida deben ser equivalentes en un sentido HTTP general.Normalización de cadenas de URI posiblemente codificadas en Java
Normalmente, esto debería ser sencillo. Sin embargo, para URI como http://blah.org/A_%28Secret%29.xml#blah
, cuyo porcentaje codifica (Secret)
, el comportamiento de java.util.URI
hace la vida más difícil.
El método de normalización debe devolver http://blah.org/A_%28Secret%29.xml
ya que los URI http://blah.org/A_%28Secret%29.xml
y http://blah.org/A_(Secret).xml
no son equivalentes en interpretación [§2.2; RFC3968]
Así que tienen los dos siguientes métodos de normalización:
URI u = new URI("http://blah.org/A_%28Secret%29.xml#blah");
System.out.println(u);
// prints "http://blah.org/A_%28Secret%29.xml#blah"
String path1 = u.getPath(); //gives "A_(Secret).xml"
String path2 = u.getRawPath(); //gives "A_%28Secret%29.xml"
//NORMALISE METHOD 1
URI norm1 = new URI(u.getScheme().toLowerCase(), u.getUserInfo(),
u.getHost().toLowerCase(), u.getPort(), path1,
u.getQuery(), null);
System.out.println(norm1);
// prints "http://blah.org/A_(Secret).xml"
//NORMALISE METHOD 2
URI norm2 = new URI(u.getScheme().toLowerCase(), u.getUserInfo(),
u.getHost().toLowerCase(), u.getPort(), path2,
u.getQuery(), null);
System.out.println(norm2);
// prints "http://blah.org/A_%2528Secret%2529.xml"
Como vemos, el URI se analiza y se reconstruyeron sin el identificador de fragmento.
Sin embargo, para el método 1, u.getPath()
devuelve un URI no codificado, que cambia el URI final.
Para el método 2, u.getRawPath()
devuelve la ruta de acceso original, pero cuando se pasa al constructor URI
, Java decide agregar una codificación doble.
Esto se siente como una trampa para los dedos en chino.
preguntas por lo que dos principales:
java.util.URI
¿Por qué sienten la necesidad de jugar con la codificación?- ¿Cómo se puede implementar este método de normalización sin alterar el porcentaje de codificación original?
(preferiría no tener que implementar los métodos de análisis/concatenación de java.util.URI
, que son no trivial.)
EDIT: Aquí hay alguna información más lejos de URI
javadoc.
El single-argumento del constructor requiere los caracteres no válidos en su argumento cotizado y conserva ninguna octetos y otros personajes que están presentes escaparon.
Los constructores de argumento múltiple citan caracteres ilegales según lo requieren los componentes en los que aparecen. El carácter de porcentaje ('%') siempre es citado por estos constructores. Cualquier otro carácter se conserva.
El getRawUserInfo, getRawPath, getRawQuery, getRawFragment, getRawAuthority, y getRawSchemeSpecificPart métodos devuelven los valores de sus componentes correspondientes en forma cruda, sin interpretar cualquier octetos escaparon. Las cadenas devueltas por estos métodos pueden contener tanto octetos escapados como otros caracteres, y no contendrán ningún carácter ilegal.
El GetUserInfo, getPath, getQuery, getFragment, getAuthority, y getSchemeSpecificPart métodos decodificar cualquier octetos escaparon en sus componentes correspondientes. Las cadenas devueltas por estos métodos pueden contener tanto otros caracteres como caracteres ilegales, y no contendrán ningún octeto escapado.
El método toString devuelve una cadena de URI con todas las comillas necesarias pero que pueden contener otros caracteres.
El método toASCIIString devuelve una cadena de URI completamente citada y codificada que no contiene ningún otro carácter.
Así que no puedo utilizar el constructor de múltiples argumento sin tener la codificación URL metido con internamente por la clase URI
. Pah!
El caso de uso es un rastreador. Nos gustaría tomar un conjunto de URI extraídos y "normalizarlos" en un conjunto lo más pequeño posible, sin dejar de garantizar que el contenido recuperado sea el mismo.(La pregunta http://stackoverflow.com/questions/2993649/how-to-normalize-a-url-in-java está relacionada, pero no aborda el problema de eliminar identificadores de fragmentos, con la codificación de URL cambiando). – badroit
Yo soy lejos de las cosas de URI, y no estoy seguro si lo necesita de la manera estándar con la API de URI, pero si solo quisiera implementar esta funcionalidad de alguna manera, yo podría 1) Obtener la subcadena de la url original hasta el primera aparición de '#' o '?' o '&' ya que eso es lo que realmente separa la URL de la información adicional o 2) Permita que el URI cree la uri normal (norm2 en el ejemplo) y luego reemplace todo el% con la original uno en la secuencia posicional (1º de norm2 con 1º de original, etc.). Por supuesto, esto es solo si la forma estándar no es utilizable. –