如何在 Java 中检查有效的 URL?

Posted

技术标签:

【中文标题】如何在 Java 中检查有效的 URL?【英文标题】:How to check for a valid URL in Java? 【发布时间】:2011-01-14 21:34:15 【问题描述】:

在 Java 中检查 URL 是否有效的最佳方法是什么?

如果尝试调用new URL(urlString) 并捕获MalformedURLException,但它似乎对以http:// 开头的任何内容感到满意。

我不关心建立连接,只关心有效性。有办法吗? Hibernate Validator 中的注释?我应该使用正则表达式吗?

编辑:一些可接受的 URL 示例是 http://***http://my favorite site!

【问题讨论】:

如果你不打算建立连接,你如何定义有效性? 你能举个例子说明URL构造函数接受的不是有效的URL吗? @mmyers:有效性应由定义 URL 的 RFC 2396 和 2732 确定。 @uckelman:几乎任何事情。 “http://***”有效。 “http://my favorite site!”有效。我无法让它抛出异常(当 http:// 开头时)。 Validating URL in Java 的可能重复项 【参考方案1】:

URI的源代码来看,

public URL(URL context, String spec, URLStreamHandler handler)

constructor 比其他构造函数做更多的验证。你可以试试那个,但是 YMMV。

【讨论】:

【参考方案2】:

最“万无一失”的方法是检查 URL 的可用性:

public boolean isURL(String url) 
  try 
     (new java.net.URL(url)).openStream().close();
     return true;
   catch (Exception ex)  
  return false;

【讨论】:

实际查询 URL 可能会导致更改、操作或跟踪。 OP 想要在不进行查询的情况下检查有效性。例如,也许这是现在存储并稍后执行,并合理保证它是有效的。【参考方案3】:

我不喜欢其中的任何一个实现(因为它们使用了一个昂贵的操作的正则表达式,或者如果你只需要一种方法,那么一个库就是一个矫枉过正的工具),所以我最终使用了 java.net.URI带有一些额外检查的类,并将协议限制为:http、https、file、ftp、mailto、news、urn。

是的,捕获异常可能是一项昂贵的操作,但可能不如正则表达式那么糟糕:

final static Set<String> protocols, protocolsWithHost;

static 
  protocolsWithHost = new HashSet<String>( 
      Arrays.asList( new String[] "file", "ftp", "http", "https"  ) 
  );
  protocols = new HashSet<String>( 
      Arrays.asList( new String[] "mailto", "news", "urn"  ) 
  );
  protocols.addAll(protocolsWithHost);


public static boolean isURI(String str) 
  int colon = str.indexOf(':');
  if (colon < 3)                      return false;

  String proto = str.substring(0, colon).toLowerCase();
  if (!protocols.contains(proto))     return false;

  try 
    URI uri = new URI(str);
    if (protocolsWithHost.contains(proto)) 
      if (uri.getHost() == null)      return false;

      String path = uri.getPath();
      if (path != null) 
        for (int i=path.length()-1; i >= 0; i--) 
          if ("?<>:*|\"".indexOf( path.charAt(i) ) > -1)
            return false;
        
      
    

    return true;
   catch ( Exception ex ) 

  return false;

【讨论】:

【参考方案4】:

我最喜欢的方法,没有外部库:

try 
    URI uri = new URI(name);

    // perform checks for scheme, authority, host, etc., based on your requirements

    if ("mailto".equals(uri.getScheme()) /*Code*/
    if (uri.getHost() == null) /*Code*/

 catch (URISyntaxException e) 

【讨论】:

【参考方案5】:

我很想将此作为评论发布到Tendayi Mawushe's answer,但恐怕没有足够的空间;)

这是来自 Apache Commons UrlValidator source 的相关部分:

/**
 * This expression derived/taken from the BNF for URI (RFC2396).
 */
private static final String URL_PATTERN =
        "/^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?/";
//         12            3  4          5       6   7        8 9

/**
 * Schema/Protocol (ie. http:, ftp:, file:, etc).
 */
private static final int PARSE_URL_SCHEME = 2;

/**
 * Includes hostname/ip and port number.
 */
private static final int PARSE_URL_AUTHORITY = 4;

private static final int PARSE_URL_PATH = 5;

private static final int PARSE_URL_QUERY = 7;

private static final int PARSE_URL_FRAGMENT = 9;

您可以从那里轻松构建自己的验证器。

【讨论】:

【参考方案6】:

这是我尝试并发现有用的方法,

URL u = new URL(name); // this would check for the protocol
u.toURI(); // does the extra checking required for validation of URI 

【讨论】:

好一个。仅使用 new URL(name) 几乎可以接受所有内容。 url.toURI();正是开发人员正在寻找的 - 无需使用其他库/框架! 这也不适用于格式错误的 URL,例如 http:/google.com。我使用了 Apache Commons 的 UrlValidator。 这个真的很危险。我看到这个例子还有很多其他的文章。 URL u = new URL(http://google).toURI(); 不会抛出异常。 @SonuOommen 可能是因为new URL(http://google) 有效^^ 我们公司有很多这样的内部域【参考方案7】:

考虑使用Apache Commons UrlValidator class

UrlValidator urlValidator = new UrlValidator();
urlValidator.isValid("http://my favorite site!");

您可以设置几个属性来控制此类的行为方式,默认情况下接受httphttpsftp

【讨论】:

它似乎不适用于 .london 等较新的域 内网url怎么样? 它不验证带有下划线的网址。 不适用于新 TLD 和本地域名,例如local 我无法让 UrlValidator 与我们奇怪的 Intranet ***域一起使用。常见的如 .com、.org 等作品。我对为此创建 RegExp 不感兴趣,因此 new URL(name).toURI() 成为解决方案。【参考方案8】:

验证器包:

似乎有一个nice package by Yonatan Matalon called UrlUtil。引用其 API:

isValidWebPageAddress(java.lang.String address, boolean validateSyntax, 
                      boolean validateExistance) 
Checks if the given address is a valid web page address.

Sun的方法-检查网络地址

Sun 的 Java 站点提供 connect attempt as a solution 用于验证 URL。

其他正则表达式代码sn-ps:

Oracle's site 和 weberdev.com 有正则表达式验证尝试。

【讨论】:

该代码用于检查链接,这是一个不同的问题。这个问题是关于 URL 的有效性,而不是是否可以建立到它的连接。 这个例子是检查URL是否可用,而不是检查它是否格式正确。 同意,添加了其他方法。

以上是关于如何在 Java 中检查有效的 URL?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查url在lua中是不是有效?

如何检查 URL 在 Android 中是不是有效

如何在 Swift 中检查 URL 的有效性?

如何检查在 iOS 的 url 中发布的用户名和密码是不是有效

如何在Swift中检查URL的有效性?

如果url有效,如何检查iphone应用程序然后加载WebVIew else show alert