Quel est le meilleur moyen de vérifier si une URL est valide en Java?
Si vous essayez d’appeler new URL(urlString)
et d’obtenir MalformedURLException
, il semble être satisfait de tout ce qui commence par http://
.
Je ne m'inquiète pas d'établir une connexion, juste de la validité. Y at-il une méthode pour cela? Une annotation dans Hibernate Validator? Devrais-je utiliser un regex?
Edit: Quelques exemples d’URL acceptées sont http://***
et http://my favorite site!
.
Envisagez d'utiliser la classe Apache Commons UrlValidator
UrlValidator urlValidator = new UrlValidator();
urlValidator.isValid("http://my favorite site!");
Il existe plusieurs propriétés que vous pouvez définir pour contrôler le comportement de cette classe. Par défaut, http
, https
et ftp
sont acceptés.
Voici comment j'ai essayé et trouvé utile,
URL u = new URL(name); // this would check for the protocol
u.toURI(); // does the extra checking required for validation of URI
J'adorerais poster ceci comme commentaire à La réponse de Tendayi Mawushe , mais j'ai bien peur qu'il n'y ait pas assez d'espace;)
Ceci est la partie pertinente de 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;
Vous pouvez facilement construire votre propre validateur à partir de là.
Mon approche préférée, sans bibliothèques externes:
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) {
}
À en juger par le code source de URI
, le
public URL(URL context, String spec, URLStreamHandler handler)
constructeur fait plus de validation que les autres constructeurs. Vous pourriez essayer celui-là, mais YMMV.
Il semble y avoir un paquet Nice de Yonatan Matalon appelé UrlUtil . Citant son API:
isValidWebPageAddress(Java.lang.String address, boolean validateSyntax,
boolean validateExistance)
Checks if the given address is a valid web page address.
Le site Java de Sun propose connect tent comme solution pour la validation des URL.
Des tentatives de validation de regex ont été effectuées sur les sites Oracle et weberdev.com .
Je n’ai aimé aucune des implémentations (car ils utilisent une Regex, opération coûteuse, ou une bibliothèque surchargée si vous n’avez besoin que d’une seule méthode). contrôles supplémentaires et limitation des protocoles à: http, https, fichier, ftp, mailto, news, urn.
Et oui, intercepter des exceptions peut être une opération coûteuse, mais probablement pas aussi grave que les expressions régulières:
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;
}
Le moyen le plus "infaillible" est de vérifier la disponibilité de l'URL. Par exemple:
public boolean isURL(String url) {
try {
(new Java.net.URL(url)).openStream().close();
return true;
} catch (Exception ex) { }
return false;
}