【问题标题】:java.net.URI chokes on special characters in host partjava.net.URI 阻塞主机部分的特殊字符
【发布时间】:2010-09-27 11:52:49
【问题描述】:

我有一个 URI 字符串,如下所示:

http://www.christlichepartei%F6sterreichs.at/steiermark/

我正在用这个字符串创建一个 java.lang.URI 实例并且它成功但是当我想检索主机时它返回 null。如果我完全按照上图所示输入,Opera 和 Firefox 也会在这个 URL 上阻塞。但是如果 URI 类无效,它不应该抛出 URISyntaxException 吗?那么如何检测到 URI 是非法的呢?

当我使用产生的 URLDecoder 解码字符串时,它的行为也相同

http://www.christlicheparteiösterreichs.at/steiermark/

现在这已被 Opera 和 Firefox 接受,但 java.net.URI 仍然不喜欢它。我该如何处理这样的 URL?

谢谢

【问题讨论】:

    标签: java http url-encoding


    【解决方案1】:

    Java 6 有 IDN 类来处理国际化域名。因此,以下生成带有编码主机名的 URI:

    URI u = new URI("http://" + IDN.toASCII("www.christlicheparteiösterreichs.at") + "/steiermark/");
    

    【讨论】:

    • IDN#toASCII 仅适用于标签或完整域名,而不是整个 URI 字符串。这可能会导致意想不到的后果。
    【解决方案2】:

    在主机名中编码非 ASCII 字符的正确方法是 "Punycode"

    【讨论】:

      【解决方案3】:

      URI 抛出 URISyntaxException,当您选择适当的构造函数时:

      URI someUri=new URI("http","www.christlicheparteiösterreichs.at","/steiermark",null);
      

      java.net.URISyntaxException:索引 28 处的主机名中存在非法字符:http://www.christlicheparteiösterreichs.at/steiermark

      您可以使用IDN 来解决此问题:

      URI someUri=new URI("http",IDN.toASCII("www.christlicheparteiösterreichs.at"),"/steiermark",null);
      System.out.println(someUri);
      System.out.println("host: "+someUri.getHost()));
      

      输出:

      http://www.xn--christlicheparteisterreichs-5yc.at/steiermark

      主机:www.xn--christlicheparteisterreichs-5yc.at

      更新关于鸡蛋问题:

      您可以让 URL 完成这项工作:

      public static URI createSafeURI(final URL someURL) throws URISyntaxException
      {
      return new URI(someURL.getProtocol(),someURL.getUserInfo(),IDN.toASCII(someURL.getHost()),someURL.getPort(),someURL.getPath(),someURL.getQuery(),someURL.getRef());    
      }
      
      
      URI raoul=createSafeURI(new URL("http://www.christlicheparteiösterreichs.at/steiermark/readme.html#important"));
      

      这只是一个速写,它并未检查所有有关将 URL 转换为 URI 的问题。以它为起点。

      【讨论】:

      • 嗨。感谢您的回答,但是当我没有 URL 的各个部分时,URI 构造函数如何帮助我。这有点像鸡和蛋的问题:)
      • 你是对的。这取决于您从哪里获取数据。如果你得到一个像“christlicheparteiösterreichs.at/steiermark”这样的字符串作为输入,你就不能在新的 URI(String) 中使用它,因为 JavaDoc 指出,它需要一个已经正确的 URI 字符串。但是这个字符串不是。您必须检查字符串在数据流中的哪个位置“损坏”。这个字符串是从哪里来的?
      • 您好,感谢您抽出宝贵时间研究此问题。您更新中的建议看起来很有希望,我可能可以使用它。再次感谢!
      猜你喜欢
      • 1970-01-01
      • 2011-09-12
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多