如何在Java中解析这样的URI

Fra*_*ank 8 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)
Run Code Online (Sandbox Code Playgroud)

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

我的方法看起来像这样:

  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(); }
  }
Run Code Online (Sandbox Code Playgroud)

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

Spi*_*ams 14

在URL中使用管道字符"被认为是不安全的".您可以通过替换|来修复它 用其编码的十六进制等效值,即"%7C"

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

因此,一个优秀的解决方案是使用语言的工具来编码URL,而不是手动操作.在Java的情况下,使用URLEncoder,根据BalusC对此问题的回答中的示例.

  • 仅供参考:`URLEncoder`(尽管名称)不应该用于编码URL.该文档说:_该类包含用于将String转换为application/x-www-form-urlencoded MIME格式的静态方法.这与URI/URL使用的编码不同. (6认同)

Fed*_*ali 13

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

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

URL url = new URL(pageURLAsUnescapedString);
URI uri = new URI(url.getProtocol(), url.getAuthority(), url.getPath(), url.getQuery(), url.getRef());
Run Code Online (Sandbox Code Playgroud)

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

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


Geo*_*Geo 7

使用URLEncoder比选择性编码东西更好吗?


Bal*_*usC 6

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

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