【问题标题】:Why UrlValidator do not work for some of my Urls?为什么 UrlValidator 不适用于我的某些 Url?
【发布时间】:2012-10-28 15:18:48
【问题描述】:
String[] schemes = {"http","https"};
UrlValidator urlValidator = new UrlValidator(schemes, UrlValidator.ALLOW_ALL_SCHEMES);
System.out.println(urlValidator.isValid(myUrl));

以下网址显示,无效。任何人都知道这是为什么。 localnet 是一个本地网络。但这适用于任何其他公共网络(似乎)。

http://aunt.localnet/songs/barnbeat.ogg

【问题讨论】:

  • UrlValidator 大概来自 apache commons?看看代码并弄清楚。可能是因为它不将 localnet 识别为 tld。
  • org.apache.commons.validator.routines.UrlValidator;

标签: java url-validation


【解决方案1】:

检查第 2 行 应该是

new UrlValidator(schemes);

如果您想允许 2 个斜线并禁止片段

new UrlValidator(schemes, ALLOW_2_SLASHES + NO_FRAGMENTS);

【讨论】:

    【解决方案2】:

    这里是isValid(String)方法的源代码:

    您可以通过手动调用检查每个步骤的结果,以了解失败的地方。

    【讨论】:

    【解决方案3】:

    正如我所想,它在顶层失败了;

    String topLevel = domainSegment[segmentCount - 1];
    if (topLevel.length() < 2 || topLevel.length() > 4) {
      return false;
    }
    

    您的顶层是localnet

    【讨论】:

    • 这适用于旧版本的 commons-validator,但如果您使用当前版本 (1.6) 中的 org.apache.commons.validator.routines.UrlValidator,则不是这样
    【解决方案4】:

    您使用的类已弃用。替换是

    org.apache.commons.validator.routines.UrlValidator

    哪个更灵活。您可以将标志 ALLOW_LOCAL_URLS 传递给构造函数,这将允许大多数地址,如您正在使用的地址。在我们的例子中,我们在地址之前有身份验证数据,因此我们必须使用更灵活的 UrlValidator(RegexValidator authorityValidator, long options) 构造函数。

    【讨论】:

    • ALLOW_LOCAL_URLS 不足以获取此类主机名的验证路径。
    • 我不得不重建权限正则表达式来跳过域段验证码:new UrlValidator(new RegexValidator("^([\\p{Alnum}\\-\\.]*)(:\\d*)?(.*)?"))
    • 感谢 Yves 使用 RegexValidator 也为我工作,否则 http://fooserver.local/ 被视为无效。我想这个正则表达式必须更改为也支持 IPV6 地址。我刚刚在他们的邮件列表markmail.org/thread/3ozz3azcnlpt4cxu 上询问是否应该扩展他们的 LOCAL_TLDS 列表。
    • @YvesMartin 您的正则表达式似乎匹配第三组中的所有内容,并且该组似乎匹配所有内容。
    【解决方案5】:

    库方法在此 URL 上失败:

      "http://en.wikipedia.org/wiki/3,2,1..._Frankie_Go_Boom"
    

    这是完全合法的 (and existing) URL。

    我通过反复试验发现下面的代码更准确:

    public static boolean isValidURL(String url)
    {
        URL u = null;
        try
        {
            u = new URL(url);
        }
        catch (MalformedURLException e)
        {
            return false;
        }
    
        try
        {
            u.toURI();
        }
        catch (URISyntaxException e)
        {  
            return false;  
        }  
    
        return true;  
    }
    

    【讨论】:

    • 请注意,这仅适用于您的 URL 已经编码的情况! URI 只接受带有编码查询参数的 URL,否则会抛出异常!
    【解决方案6】:

    您可以使用以下内容:

    UrlValidator urlValidator = new UrlValidator(schemes, new RegexValidator("^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$"), 0L);
    

    【讨论】:

    • 这不允许给出任何端口,并且最后一部分只能是您的正则表达式中定义的最多 6 个字符{2,6}
    【解决方案7】:

    这已在 Apache Validator 的 1.4.1 版本中得到修复:

    https://issues.apache.org/jira/browse/VALIDATOR-342 https://issues.apache.org/jira/browse/VALIDATOR/fixforversion/12320156

    简单升级到最新版本的验证器应该可以很好地解决问题。

    【讨论】:

    • VALIDATOR-342 错误是另一个问题。是因为 .rocks TLD。 “.rocks TLD 是最新的,不包含在域验证器使用的列表中。”
    • 谢谢@drchuck!它对我的情况有所帮助。我被谷歌欺骗了。他们将 commons-validator 1.4.0 显示为第一个结果,而当前版本是 1.5.1!
    猜你喜欢
    • 2013-08-12
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    相关资源
    最近更新 更多