Java的URL无法正确解析字符串

时间:2015-11-20 13:40:43

标签: java url

我正在创建一个网址变量:

URL inputURL = null;
try {
    inputURL = new URL(inputUrlString);
} catch (MalformedURLException e) {
    Log.e(TAG, "Bad Parsing.");
    e.printStackTrace();

    AlertDialog ad = new AlertDialog.Builder(this)
            .setTitle("Error")
            .setMessage("URL is not HTTP-like url.")
            .setCancelable(true).create();
    ad.show();
}

如果inputUrlString"http:""http:/""http:/rubbish"它就会解析它就好了,进一步粉碎一切。它真的是一个有效的URL吗?解析它的一个好习惯是通过Pattern类吗?

5 个答案:

答案 0 :(得分:1)

  

抛出:
  MalformedURLException - 如果未指定协议,或找到未知协议,或者spec为null。

正如您在the URL javadoc中看到的那样,构造函数本身相当宽松。

您可以使用apache common UrlValidator,或者只是在使用网址时注意错误。

答案 1 :(得分:1)

如果您(例如)想要查看它是否是电子邮件地址,则仅分析解析URL似乎是有意义的。你不能告诉Java看起来'如果您/用户输入了垃圾。如果浏览器/任何试图访问它的话,你可以捕获抛出的异常。

有关如何在Java中使用URL的信息,请参阅the oracle documentation

查看this帖子,也许这就是您要找的内容。

答案 2 :(得分:0)

  

解析它是一种很好的做法是通过Pattern类吗?

我想这取决于inputUrlString的来源。如果它是用户正在输入的东西,那么擦除它总是一个好主意。

答案 3 :(得分:0)

正如您所看到的,URL对象具有在使用URL(String)时调用的构造函数,即

URL(URL, String, URLStreamHandler)

在此构造函数中,您有一个测试来检查输入的String是否包含:以及在:是已知协议之前发生的情况。请参阅下面的代码

CODE

如您所见,以下部分检查':'是否存在。找到它时,它会通过方法isValidProtocol检查之前的文本是否是有效的已知协议。这就是http:是构造函数的有效String的原因。

540                 for (i = start ; !aRef && (i < limit) &&
541                      ((c = spec.charAt(i)) != '/') ; i++) {
542                 if (c == ':') {
543 
544                     String s = spec.substring(start, i).toLowerCase();
545                     if (isValidProtocol(s)) {
546                         newProtocol = s;
547                         start = i + 1;
548                     }
549                     break;
550                 }

isValidProtocol方法

623     /*
624      * Returns true if specified string is a valid protocol name.
625      */
626     private boolean isValidProtocol(String protocol) {
627         int len = protocol.length();
628         if (len < 1)
629             return false;
630         char c = protocol.charAt(0);
631         if (!Character.isLetter(c))
632             return false;
633         for (int i = 1; i < len; i++) {
634             c = protocol.charAt(i);
635             if (!Character.isLetterOrDigit(c) && c != '.' && c != '+' &&
636                 c != '-') {
637                 return false;
638             }
639         }
640         return true;
641     }

Source

答案 4 :(得分:0)

你有两个问题,其中只有一个你已经遇到过。

<强> 1。请勿使用URL

URL class做了一些你基本上不想要的奇怪和意想不到的事情。例如,URL.equals method州(强调我的):

  

如果两个主机名都可以解析为相同的IP地址[...]

,则认为两台主机是等效的      

由于主机比较需要名称解析,因此此操作是阻止操作

     

注意:已知已定义的equals行为与HTTP中的虚拟主机不一致。

请改用URI。它的文档描述了URL类的一些其他缺点,包括:

  • 并非所有URI都可以表示为URL:

    • 网址必须是绝对的(以“方案:”开头)。

    • 您无法为尚未拥有(流)处理程序的方案创建URL

  • 未定义比较。

  • URL.equalsURL.hashCode在访问互联网时都会阻止。

  • 对象相等(和哈希码)可能因您的DNS设置而异...一台计算机上的两个“相等”URL对象可能 un - 等于另一台计算机

让人惊讶。

<强> 2。你的期望是错误的。

像“http:sdfasdfasdfas”这样的URI没有什么问题。它甚至可以在许多浏览器中运行...如果您碰巧有一个名为“sdfasdfasdfas”的本地主机,它可以提供网页。

“URI语法和组件”下的URI class docs定义了由以下部分组成的URI:

  

[方案:]方案特定部分[#片段]

您的示例“http:sdfasdfasdfas”有一个方案,使其成为“绝对URI”。它还有一个特定于方案的部分,但没有片段。关于计划特定部分......

  

opaque URI是一个绝对URI,其特定于方案的部分不以斜杠字符('/')开头。 不透明的URI不需要进一步解析。不透明URI的一些示例是:

     
      
  • mailto:java-net@java.sun.com
  •   
  • news:comp.lang.java
  •   
  • 瓮:ISBN:096139210x
  •   

您的示例是 opaque URI,其特定于方案的部分几乎可以是任何内容,包括奇怪的“主机名”。

您的其他示例也是有效的URI,但有一个例外:

  • “http:”将是绝对不透明的URI,但它缺少所需的特定于方案的部分。 (“”还不够好。)

  • “http:/”是一个绝对的分层URI,方案为“http:”,路径为“/".

  • “http:/ rubbish”是相同的,但路径为“/ rubbish”。

如果您希望URI类(或URL类,如果您坚持)为您验证不透明的URI,则必须“知道”如何定义有效的特定于方案的部分所有方案 ......包括尚不存在的方案。

<强>结论

如果你真的想要,你可以声明像你的例子一样有效的URI是无效的,但你可能需要编写自己的东西来抛出MalformedURLException,或者最好是你自己更具体的例外

我认为你最好接受世界其他地方使用的“URI”定义,并花时间修复任何代码阻塞有效URI的时间。