2010-09-22 14 views
16

tengo el siguiente escenario:manera adecuada para comprobar la igualdad URL

URL u1 = new URL("http://www.yahoo.com/"); 
URL u2 = new URL("http://www.yahoo.com"); 

if (u1.equals(u2)) { 
    System.out.println("yes"); 
} 
if (u1.toURI().equals(u2.toURI())) { 
    System.out.println("uri equality"); 
} 
if (u1.toExternalForm().equals(u2.toExternalForm())) { 
    System.out.println("external form equality"); 
} 
if (u1.toURI().normalize().equals(u2.toURI().normalize())) { 
    System.out.println("uri normalized equality"); 
} 

Ninguno de estos controles están teniendo éxito. Solo la ruta difiere: u1 tiene una ruta de "/" mientras que u2 tiene una ruta de "". ¿Estas URL apuntan al mismo recurso y hay alguna manera de que verifique tal cosa sin abrir una conexión? ¿Estoy malentendiendo algo fundamental sobre las URL?

EDIT Debo decir que se desea una verificación no hacky. ¿Es razonable decir que el camino vacío == /? Tenía la esperanza de no tener este tipo de código

Respuesta

21

Desde el JavaOne 2007:

La segunda rompecabezas, acertadamente titulado "Más alegrías de Conjuntos" tiene el usuario a crear claves HashMap que consisten o varios objetos de URL. Una vez más, la mayoría de la audiencia no pudo adivinar la respuesta correcta.

Lo importante que el público aprendió aquí es que el método de igual a() del objeto URL está, en efecto, roto. En este caso, dos objetos URL son iguales si se resuelven en la misma dirección IP y puerto, no solo si tienen cadenas iguales. Sin embargo, Bloch y Pugh señalan un talón de Aquiles aún más severo: el comportamiento de igualdad varía dependiendo de si estás conectado a la red, donde las direcciones virtuales pueden resolverse en el mismo host, o si no estás en la red, donde la resolución es una operación de bloqueo. Por lo tanto, en cuanto a las lecciones aprendidas, recomiendan:

No utilizar URL; use URI en su lugar. URI no intenta comparar direcciones o puertos. Además, no use la URL como un elemento Establecer o una clave de Mapa.
Para los diseñadores de API, el método equals() no debe depender del entorno. Por ejemplo, en este caso, la igualdad no debería cambiar si una computadora está conectada a Internet o no.


Desde el URI es igual a la documentación:

Durante dos URIs jerárquicas que se consideran iguales, sus caminos deben ser iguales y sus consultas deben ya sea tanto ser indefinido o de lo contrario ser iguales.

En su caso, las dos rutas son diferentes. uno es "/" el otro es "".


De acuerdo con la RFC URI §6.2.3:

Implementaciones puede uso reglas específica del esquema, en aún más el coste de procesamiento , para reducir la probabilidad de falsos negativos.Por ejemplo, porque el esquema "http" hace uso de un componente de autoridad, tiene un puerto predeterminado de "80" y define una ruta vacía equivalente a "/", los siguientes cuatro URI son equivalentes:

http://example.com 
http://example.com/ 
http://example.com:/ 
http://example.com:80/ 

Parece que esta implementación no utiliza reglas específicas de esquema.


Recursos:

+3

... esto no responde a la pregunta en absoluto. – Zarel

+0

Interesante ... pero entonces la prueba toURI() tendría éxito si de hecho fueran iguales. –

+0

@SB, actualizado con más RFC y más documentación :) –

2

En sentido estricto no son equ Alabama. La barra inclinada opcional (/) es solo un uso común pero no obligatorio. Se podría mostrar diferentes páginas de

http://www.yahoo.com/foo/ 

y para

http://www.yahoo.com/foo 

Es incluso posible que el uno que ya ha proporcionado Creo que la cabecera HTTP podría saltar esa barra.

+0

Correcto, pero ¿puede haber una lógica que cambie www.yahoo.com y www.yahoo.com/? –

+7

'example.com/foo /' y 'example.com/foo' son diferentes, sí, pero' example.com' y 'example.com /' son exactamente iguales. – Zarel

0

Siempre se puede comparar con URLs relativas Path.equals método

ex.

Paths.get("/user/login").equals(Paths.get("/user/login/"))) 

productos cierto

También puede utilizar startsWith/endsWith-métodos

+0

¿Esto funcionará para uri también? – SAVVY

+0

no hay clases como Paths – SAVVY

Cuestiones relacionadas