web-dev-qa-db-fra.com

Comment vérifier une URL valide en Java?

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!.

80
Eric Wilson

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.

88
Tendayi Mawushe

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 
52
Prasanna Pilla

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à.

6
user123444555621

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) {
}
4
Andrei Volgin

À 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.

3
uckelman

forfait validateur:

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.

Approche de Sun - vérifiez l'adresse réseau

Le site Java de Sun propose connect tent comme solution pour la validation des URL.

Autres extraits de code regex:

Des tentatives de validation de regex ont été effectuées sur les sites Oracle et weberdev.com .

3
Adam Matan

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

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