我正在创建一个网址变量:
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类吗?
答案 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是否包含:
以及在:
是已知协议之前发生的情况。请参阅下面的代码
如您所见,以下部分检查':'
是否存在。找到它时,它会通过方法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 }
答案 4 :(得分:0)
你有两个问题,其中只有一个你已经遇到过。
<强> 1。请勿使用URL
!
URL
class做了一些你基本上不想要的奇怪和意想不到的事情。例如,URL.equals
method州(强调我的):
如果两个主机名都可以解析为相同的IP地址[...]
,则认为两台主机是等效的由于主机比较需要名称解析,因此此操作是阻止操作。
注意:已知已定义的equals行为与HTTP中的虚拟主机不一致。
请改用URI
。它的文档描述了URL
类的一些其他缺点,包括:
并非所有URI都可以表示为URL:
网址必须是绝对的(以“方案:”开头)。
您无法为尚未拥有(流)处理程序的方案创建URL
。
未定义比较。
URL.equals
和URL.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的时间。