如何在Java中解析这样的URI

时间:2009-12-01 20:22:34

标签: java parsing uri

我正在尝试解析以下URI:http://translate.google.com/#zh-CN|en|你

但收到此错误消息:

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)

“|”有问题如果我摆脱“|”,最后一个中文字符没有引起任何问题,处理这个问题的正确方法是什么?

我的方法如下:

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

感谢您的回答,但是BalusC的解决方案似乎只适用于url的一个实例,我的方法需要处理我传递给它的任何url,它怎么知道将url切成两部分的起点在哪里并只编码第二部分?

7 个答案:

答案 0 :(得分:13)

管道字符"considered unsafe"用于在URL中使用。您可以通过替换|来修复它使用其编码的十六进制等效值,即“%7C”

但是,替换URL中的单个字符是一种脆弱的解决方案,如果您认为在任何给定的URL中可能存在可能需要替换的大量不同字符,则该方法效果不佳。您已经在替换空格,插入符号和管道....但是括号,重音符号和引号呢?或问号和&符号,它们可能是也可能不是URL的有效部分,具体取决于它们的使用方式?

因此,一个优秀的解决方案是使用语言的工具来编码URL,而不是手动操作。对于Java,请使用URLEncoder,按照BalusC对此问题的回答中的示例。

答案 1 :(得分:12)

URLEncoder解决方案对我不起作用,可能是因为它只对所有内容进行编码。我试图使用apache的HttpGet,它会像一个字符串编码那样抛出错误。

在我的情况下,正确的方法是这个奇怪的代码:

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

不知何故,url.toURI的工作方式不同。 URI构造函数以两种方式工作:如果使用具有单个String参数的构造函数,构造函数假装提供的uri被正确转义(因此错误,HttpGet的String构造函数也会发生错误);如果你使用多个Strings URI构造函数,那么该类处理非常好的一切(HttpGet有另一个接受URI的构造函数)。为什么URL.toURI()不这样做?我不知道......

希望它对某人有所帮助,我花了几个小时来弄明白。

答案 2 :(得分:7)

使用URLEncoder比使用有选择地编码内容更好吗?

答案 3 :(得分:6)

您应该使用java.net.URLEncoderUTF-8的查询进行网址编码。你不一定需要正则表达式。你不想要一个正则表达式来覆盖所有这些数千个中国字形,对吗? ;)

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

答案 4 :(得分:3)

充分利用Federico's answerMarek's answer,您需要执行以下操作:

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

答案 5 :(得分:0)

首先对您的网址进行编码,请使用以下示例,然后将网址传递给方法

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

//现在调用方法 displayFileOrUrlInBrowser(createdJson);

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

答案 6 :(得分:-1)

好吧,我发现了怎么做,就像这样:

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