2009-12-01 9 views
7

Sto cercando di analizzare il seguente URI: http://translate.google.com/#zh-CN|en|你Come fare il parsing di un URI come questo in Java

ma ha ottenuto questo messaggio di errore:

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) 

Sta avendo problemi con il "|" personaggio, se mi sbarazzo del "|", l'ultimo carattere cinese non sta causando alcun problema, qual è il modo giusto per gestirlo?

Il mio metodo simile a questa:

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(); } 
    } 

Grazie per le risposte, ma la soluzione di BalusC sembra funzionare solo per un'istanza del URL, il mio metodo ha bisogno di lavorare con qualsiasi URL passo ad esso, come Saprebbe dov'è il punto di partenza per tagliare l'url in due parti e codificare solo la seconda parte?

risposta

13

Il carattere del tubo è "considered unsafe" per l'utilizzo negli URL. Puoi aggiustarlo sostituendo il | con il suo equivalente esadecimale codificato, che sarebbe "% 7C"

Tuttavia, la sostituzione di singoli caratteri in un URL è una soluzione fragile che non funziona molto bene se si considera che, in un dato URL, ci potrebbe potenzialmente essere abbastanza un numero di caratteri diversi che potrebbero dover essere sostituiti. Stai già sostituendo spazi, accenti circolari e tubi ... ma per quanto riguarda le parentesi, i segni di accento e le virgolette? O punti interrogativi ed e commerciali, che possono o meno parti valide di un URL, a seconda di come vengono utilizzati?

Pertanto, una soluzione di livello superiore sarebbe utilizzare la funzionalità del linguaggio per la codifica degli URL, anziché eseguirla manualmente. Nel caso di Java, utilizzare URLEncoder, come nell'esempio nella risposta di BalusC a questa domanda.

+6

FYI: 'URLEncoder' (nonostante il nome) non deve essere utilizzato per codificare gli URL. Il doc dice: _Questa classe contiene metodi statici per convertire una stringa nel formato MIME application/x-www-form-urlencoded. Questo non è lo stesso della codifica usata dagli URI/URL. – McDowell

+0

La soluzione di BalusC sembra funzionare per questa istanza dell'URL, ma ho bisogno che il metodo funzioni per tutti gli URL che ho passato, come saprebbe da quale punto di partenza analizzare il resto dell'URL? L'URL potrebbe una delle seguenti: www.yahoo.com/abc/xyz http://yahoo.com/abc/123/ yahoo.com/abc/123/... – Frank

+0

I pensa che sarebbe necessario dividere l'URL in parti ... dominio, percorso, stringa di query e frammento. Il dominio non dovrebbe essere codificato. Il percorso, dovresti separarti dalle barre e codificare ogni parte del percorso, quindi rimetterlo insieme. Per la stringa di query, è necessario codificare ogni nome e valore di parametro. Dovresti anche codificare il frammento. Quindi, riassembla l'URL. –

-1

Va bene, ho trovato come farlo, in questo modo:

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

Usa URLEncoder. –

7

non sei meglio utilizzare URLEncoder rispetto alla codifica selettivamente roba?

6

È necessario utilizzare java.net.URLEncoder per codificare l'URL della query con UTF-8. Non hai necessariamente bisogno di regex per questo. Non vuoi avere un'espressione regolare per coprire tutte quelle migliaia di glifi cinesi, vero? ;)

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

La soluzione URLEncoder non ha funzionato per me, forse perché codifica solo tutto. Stavo cercando di usare HttpGet di Apache e genera un errore con un url come stringa codificata in quel modo.

Il modo corretto nel mio caso è stato questo strano codice:

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

In qualche modo url.toURI non funziona allo stesso modo. I costruttori URI funzionano in due modi: se si utilizza quello con un singolo parametro String, il costruttore pretende che l'uri fornito sia correttamente scappato (e quindi l'errore, lo stesso accade con il costruttore String di HttpGet); se si utilizza il costruttore di URI di stringhe multiple, la classe gestisce molto bene il campo non sottoposto a escape (e HttpGet ha un altro costruttore che accetta un URI). Perché URL.toURI() non lo fa? Non ho idea ...

Spero che aiuti qualcuno, mi ci sono volute alcune ore per capirlo.

+0

Questo è sbagliato. Se l'URL contiene alcuni caratteri codificati, ad esempio, lo spazio "% 20", come risultato ci sarà "% 2520" indesiderato. Guarda un esempio [qui] (http://ideone.com/7uVSBj) o [la mia domanda e risposta] (http://stackoverflow.com/q/13530019/1387438). –

+1

@MarekR Ho preso la migliore delle due risposte e le ho combinate all'indirizzo http://stackoverflow.com/a/22279061/14731 – Gili

3

Prendendo il meglio del Federico's answer e Marek's answer, è necessario effettuare le seguenti operazioni:

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 (query," UTF-8 ")' decodificherà la e commerciale anche nei valori dei parametri presto – giorgiga

0

Prima codificare l'URL, si prega di utilizzare seguente, quindi passare URL in modo

 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"); 

// chiamare ora il metodo displayFileOrUrlInBrowser (createdJson);

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