如何在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!");
您可以设置几个属性来控制此类的行为,默认情况下,接受http
, https
和ftp
。
这是我试过的方式,发现有用的,
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; }