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

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

如果试图调用new URL(urlString)并获取一个MalformedURLException ,但似乎对以http://开头的任何事情感到满意。

我不关心build立连接,只是有效性。 有没有这样的方法? Hibernate Validator中的注释? 我应该使用正则expression式吗?

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

考虑使用Apache Commons UrlValidator类

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

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

这是我试过的方式,发现有用的,

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

我很想把这个post作为对Tendayi Mawushe的回答的评论,但是恐怕没有足够的空间;)

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

 /** * 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; 

你可以轻松地从那里build立你自己的validation器。

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

 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) { } 

validation程序包:

Yonatan Matalon似乎有一个叫UrlUtil的包 。 引用其API:

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

Sun的方法 – 检查networking地址

Sun的Java站点提供连接尝试作为validationURL 的解决scheme 。

其他正则expression式代码片段:

在Oracle网站和weberdev.com上都有正则expression式validation尝试。

URI的源代码判断,

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

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

我不喜欢任何的实现(因为他们使用一个昂贵的操作正则expression式,或者如果你只有一个方法是一个矫枉过正的库),所以我最终使用java.net.URI类与一些额外的检查和限制协议:http,https,文件,ftp,mailto,新闻,瓮。

是的,捕捉exception可能是一个昂贵的操作,但可能不像正则expression式那样糟糕:

 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; }