检查URL在Java中是否有效的最佳方法是什么?
如果尝试拨打new URL(urlString)
并抓住MalformedURLException
,但似乎对以http://
开头的任何内容感到满意。
我并不关心建立联系,只关心有效性。有这个方法吗? Hibernate Validator中的注释?我应该使用正则表达式吗?
修改:已接受网址的一些示例包括http://***
和http://my favorite site!
。
答案 0 :(得分:90)
考虑使用Apache Commons UrlValidator class
UrlValidator urlValidator = new UrlValidator();
urlValidator.isValid("http://my favorite site!");
您可以设置几个属性来控制此类的行为方式,默认情况下http
,https
和ftp
被接受。
答案 1 :(得分:54)
这是我尝试过的方式,并且发现有用,
URL u = new URL(name); // this would check for the protocol
u.toURI(); // does the extra checking required for validation of URI
答案 2 :(得分:6)
我想将此作为对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;
您可以从那里轻松构建自己的验证器。
答案 3 :(得分: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) {
}
答案 4 :(得分:4)
最“简单”的方法是检查URL的可用性:
public boolean isURL(String url) {
try {
(new java.net.URL(url)).openStream().close();
return true;
} catch (Exception ex) { }
return false;
}
答案 5 :(得分:3)
好像有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的Java网站提供connect attempt as a solution来验证网址。
在Oracle's site和weberdev.com进行了正则表达式验证尝试。
答案 6 :(得分:3)
根据URI
的源代码判断,
public URL(URL context, String spec, URLStreamHandler handler)
构造函数比其他构造函数执行更多验证。你可以尝试那个,但是YMMV。
答案 7 :(得分:2)
我不喜欢任何实现(因为他们使用的是一个昂贵的操作的Regex,或者如果你只需要一个方法就是一个过度的库),所以我最终使用了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;
}