2009-12-01 8 views
7

Estoy tratando de analizar el siguiente URI: http://translate.google.com/#zh-CN|en|你Cómo analizar un URI como esta en Java

pero obtenido este mensaje de error:

java.net.URISyntaxException: Illegal character in fragment at index 34: http://translate.google.com/#zh-CN|en|你 
     at java.net.URI$Parser.fail(URI.java:2809) 
     at java.net.URI$Parser.checkChars(URI.java:2982) 
     at java.net.URI$Parser.parse(URI.java:3028) 

Se trata de tener un problema con el "|" personaje, si me deshago del "|", el último char chino no está causando ningún problema, ¿cuál es la forma correcta de manejar esto?

Mi aspecto método como este:

public static void displayFileOrUrlInBrowser(String File_Or_Url) 
    { 
    try { Desktop.getDesktop().browse(new URI(File_Or_Url.replace(" ","%20").replace("^","%5E"))); } 
    catch (Exception e) { e.printStackTrace(); } 
    } 

Gracias por las respuestas, pero la solución de BalusC parece que funciona sólo para una instancia de la url, mi método necesita trabajar con cualquier URL que pase a ella, cómo ¿Sabría dónde está el punto de partida para cortar la url en dos partes y solo codificar la segunda parte?

Respuesta

13

El carácter de la tubería es "considered unsafe" para su uso en las URL. Puede solucionarlo reemplazando el | con su equivalente hexadecimal codificado, que sería "% 7C"

Sin embargo, reemplazar caracteres individuales en una URL es una solución frágil que no funciona muy bien si tenemos en cuenta que, en cualquier URL dada, podría haber bastante un número de caracteres diferentes que pueden necesitar ser reemplazados. Ya está reemplazando espacios, caretas y tuberías ... pero ¿qué pasa con los corchetes, los acentos y las comillas? ¿O signos de interrogación y símbolos, que pueden o no ser partes válidas de una URL, según cómo se utilicen?

Por lo tanto, una solución superior sería utilizar las instalaciones del lenguaje para codificar las URL, en lugar de hacerlo manualmente. En el caso de Java, use URLEncoder, según el ejemplo en la respuesta de BalusC a esta pregunta.

+6

FYI: 'URLEncoder' (a pesar del nombre) no se debe utilizar para codificar URL. El documento dice: _Esta clase contiene métodos estáticos para convertir un String a la aplicación/x-www-form-urlencoded formato MIME._ Esto no es lo mismo que la codificación utilizada por URIs/URLs. – McDowell

+0

La solución de BalusC parece funcionar para esta instancia de la url, pero necesito que el método funcione para todas las URL que paso a él, ¿cómo sabría desde qué punto de partida analizar el resto de la URL? La url podría cualquier de los siguientes: www.yahoo.com/abc/xyz http://yahoo.com/abc/123/ yahoo.com/abc/123/... – Frank

+0

I cree que debería dividir la URL en pedazos ... dominio, ruta, cadena de consulta y fragmento. El dominio no debe ser codificado. El camino, tendrías que dividir por barras, y codificar cada parte del camino, luego volver a unirlo. Para la cadena de consulta, necesitarás codificar el nombre y el valor de cada parámetro. También deberías codificar el fragmento. Luego, vuelve a armar la URL. –

-1

bien, he encontrado la forma de hacerlo, de esta manera:

try { Desktop.getDesktop().browse(new URI(File_Or_Url.replace(" ","%20").replace("^","%5E").replace("|","%7C"))); } 
catch (Exception e) { e.printStackTrace(); } 
+1

Use URLEncoder. –

7

No estás mejor usar URLEncoder de codificar selectivamente cosas?

6

Debe usar java.net.URLEncoder para codificar URL la consulta con UTF-8. No necesariamente necesitas expresiones regulares para esto. No quieres tener una expresión regular para cubrir todos esos miles de glifos chinos, ¿verdad? ;)

String query = URLEncoder.encode("zh-CN|en|你", "UTF-8"); 
String url = "http://translate.google.com/#" + query; 
Desktop.getDesktop().browse(new URI(url));  
10

La solución URLEncoder no funcionó para mí, quizás porque codifica todo. Estaba intentando usar HttpGet de apache y arroja un error con una url como una cadena codificada de esa manera.

La forma correcta en mi caso era este extraño código:

URL url = new URL(pageURLAsUnescapedString); 
URI uri = new URI(url.getProtocol(), url.getAuthority(), url.getPath(), url.getQuery(), url.getRef()); 

De alguna manera url.toURI no funciona de la misma manera. Los constructores de URI funcionan de dos maneras: si usas el que tiene un solo parámetro de cadena, el constructor pretende que el uri provisto está escapado correctamente (y por lo tanto el error, lo mismo ocurre con el constructor de cadenas de HttpGet); si usa el constructor de URI de múltiples cadenas, la clase maneja todo lo que no está guardado muy bien (y HttpGet tiene otro constructor que acepta un URI). ¿Por qué URL.toURI() no hace esto? No tengo ni idea ...

Espero que ayude a alguien, me tomó algunas horas para resolverlo.

+0

Esto está mal. Si la URL contiene algunos caracteres codificados, espacio "% 20" por ejemplo, como resultado habrá "% 2520" no deseado. Mire un ejemplo [aquí] (http://ideone.com/7uVSBj) o [mi pregunta y respuesta] (http://stackoverflow.com/q/13530019/1387438). –

+1

@MarekR Tomé la mejor de sus dos respuestas y las combiné en http://stackoverflow.com/a/22279061/14731 – Gili

3

Tomando lo mejor de Federico's answer y Marek's answer, tiene que hacer lo siguiente:

URL url = new URL(pageURLAsUnescapedString); 

// URI's constructor expects the path, query string and fragment to be decoded. 
// If we do not decode them, we will end up with double-encoding. 
String path = url.getPath(); 
if (path != null) 
    path = URLDecoder.decode(path, "UTF-8"); 
String query = url.getQuery(); 
if (query != null) 
    query = URLDecoder.decode(query, "UTF-8"); 
String fragment = url.getRef(); 
if (fragment != null) 
    fragment = URLDecoder.decode(fragment, "UTF-8"); 

URI uri = new URI(url.getProtocol(), url.getAuthority(), path, query, fragment); 
+0

'URLDecoder.decode (consulta," UTF-8 ")' también decodificará el signo & en los valores de los parámetros temprano – giorgiga

0

Primera codificar el URL, por favor utilice ejemplo siguiente, luego pasar URL en el método

 JSONObject json = new JSONObject(); 
     json.put("name", "vaquar"); 
     json.put("age", "30"); 
     json.put("address", "asasbsa bajsb "); 


     System.out.println("in sslRestClientGETRankColl"+json.toString()); 

     String createdJson=json.toString(); 

     createdJson= URLEncoder.encode(createdJson, "UTF-8"); 

// llame ahora al método displayFileOrUrlInBrowser (createdJson);

public static void displayFileOrUrlInBrowser(String File_Or_Url) 
    { 
    try { Desktop.getDesktop().browse(File_Or_Url); } 
    catch (Exception e) { e.printStackTrace(); } 
    } 
Cuestiones relacionadas