2009-12-01 9 views
7

Ich versuche, die folgende URI zu analysieren: http://translate.google.com/#zh-CN|en|你Wie eine URI wie dies in Java analysieren

bekam aber diese Fehlermeldung:

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) 

Es hat das Problem mit dem „|“ Charakter, wenn ich das "|" loswerde, verursacht das letzte chinesische Zeichen kein Problem, was ist der richtige Weg, damit umzugehen?

Meine Methode sieht wie folgt aus:

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

Danke für die Antworten, aber BalusC Lösung nur arbeiten für eine Instanz der URL scheint, muss meine Methode mit einer beliebigen URL ich es passieren arbeiten, wie Würde es wissen, wo der Ausgangspunkt ist, um die URL in zwei Teile zu zerlegen und nur den zweiten Teil zu codieren?

Antwort

13

Die Rohrfigur ist "considered unsafe" zur Verwendung in URLs. Sie können es beheben, indem Sie das | ersetzen mit seinem codierten hex-Äquivalent, das wäre "% 7C"

Allerdings ist das Ersetzen einzelner Zeichen in einer URL eine spröde Lösung, die nicht sehr gut funktioniert, wenn man bedenkt, dass es in jeder gegebenen URL möglicherweise recht sein könnte eine Anzahl von verschiedenen Zeichen, die möglicherweise ersetzt werden müssen. Sie ersetzen bereits Leerzeichen, Cursor und Pipes .... aber was ist mit Klammern, Akzentzeichen und Anführungszeichen? Oder Fragezeichen und Et-Zeichen, die gültige Teile einer URL sein können oder nicht, je nachdem, wie sie verwendet werden?

Somit wird eine bessere Lösung wäre, sich die Einrichtung Sprache URLs für die Codierung zu verwenden, anstatt es manuell zu tun. Verwenden Sie im Fall von Java URLEncoder, wie im Beispiel in BalusCs Antwort auf diese Frage.

+6

FYI: 'URLEncoder' (trotz des Namens) sollte nicht verwendet werden, um URLs zu kodieren. Das Dokument sagt: _This Klasse enthält statische Methoden zum Konvertieren einer Zeichenfolge in die Anwendung/x-www-Form-urlencoded MIME-Format. Dies ist nicht das Gleiche wie die Codierung von URIs/URLs verwendet. – McDowell

+0

Die Lösung von BalusC scheint für diese Instanz der URL zu funktionieren, aber ich muss die Methode für alle URLs verwenden, die ich an sie weitergebe. Woher weiß sie, von welchem ​​Startpunkt aus der Rest der URL analysiert wird? Die URL könnte eine der folgenden Aktionen: www.yahoo.com/abc/xyz http://yahoo.com/abc/123/ yahoo.com/abc/123/... – Frank

+0

I Ich denke, Sie müssten die URL in Teile aufteilen ... Domäne, Pfad, Abfragezeichenfolge und Fragment. Die Domain sollte nicht verschlüsselt werden. Der Pfad, den du durch Schrägstriche aufteilen musst, kodiere jeden Teil des Pfades und setze ihn dann wieder zusammen. Für die Abfragezeichenfolge müssten Sie jeden Parameternamen und -wert codieren. Sie müssten auch das Fragment kodieren. Platzieren Sie dann die URL erneut. –

-1

Okay, fand ich, wie es zu tun, wie folgt aus:

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

Verwenden Sie URLEncoder. –

7

Sind Sie mit URLEncoder als selektiv kodieren Sachen nicht besser dran?

6

sollten Sie java.net.URLEncoder verwenden, um die Abfrage mit UTF-8 URL-Codierung. Sie brauchen dafür nicht unbedingt Regex. Du willst keine Regex haben, um all diese tausenden chinesischen Glyphen abzudecken, oder? ;)

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

Die URLEncoder-Lösung hat bei mir nicht funktioniert, vielleicht weil sie einfach alles codiert. Ich habe versucht, Apache HttpGet zu verwenden, und es wirft Fehler mit einer URL als Zeichenfolge codiert.

Der richtige Weg in meinem Fall war dieser seltsame Code:

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

Irgendwie url.toURI die gleiche Weise funktioniert nicht. URI Konstrukteure arbeiten auf zwei Arten: wenn Sie das mit einem einzigen String-Parameter verwenden, gibt vor, der Konstruktor die mitgelieferte uri richtig entkommen ist (und damit der Fehler, das gleiche geschieht mit dem String-Konstruktor von HttpGet); wenn Sie die mehrere Strings URI Konstruktor verwenden, dann übernimmt die Klasse alles sehr gut unescaped (und HttpGet hat einen anderen Konstruktor eine URI zu akzeptieren). Warum URL.toURI() dies nicht tut? Ich habe keine Ahnung ...

Hoffe, dass es jemand hilft, es hat mich ein paar Stunden, um es herauszufinden.

+0

Das ist falsch. Wenn die URL einige codierte Zeichen enthält, z. B. Leerzeichen "% 20", wird das unerwünschte "% 2520" angezeigt. Werfen Sie einen Blick auf Beispiel [hier] (http://ideone.com/7uVSBj) oder [meine Frage und Antwort] (http://stackoverflow.com/q/13530019/1387438). –

+1

@MarekR Ich nahm das Beste aus Ihren zwei Antworten und kombinierte sie unter http://stackoverflow.com/a/22279061/14731 – Gili

3

verbindet die Vorteile von Federico's answer und Marek's answer, müssen Sie folgendes tun:

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 (Abfrage," UTF-8 ")' wird kaufmännisches Und in Parameterwerten zu dekodieren früh – giorgiga

0

Erste kodieren Ihre URL bitte folgende Beispiel verwenden, dann URL übergeben in Methode

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

// Rufmethode jetzt displayFileOrUrlInBrowser (createdJson);

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