103 votes

Comment vérifier la validité d'une URL en Java ?

Quelle est la meilleure façon de vérifier si une URL est valide en Java ?

Si vous avez essayé d'appeler new URL(urlString) et attraper un MalformedURLException mais il semble se contenter de tout ce qui commence par http:// .

Je ne suis pas préoccupé par l'établissement d'une connexion, juste par la validité. Existe-t-il une méthode pour cela ? Une annotation dans le validateur Hibernate ? Devrais-je utiliser une expression rationnelle ?

Edit : Voici quelques exemples d'URLs acceptées http://*** et http://my favorite site! .

0 votes

Comment définir la validité si vous n'établissez pas de connexion ?

2 votes

Pouvez-vous donner un exemple de quelque chose qui n'est pas une URL valide et que la URL Le constructeur accepte ?

1 votes

@mmyers : La validité devrait être déterminée par les RFC 2396 et 2732, celles qui définissent ce qu'est une URL.

105voto

Tendayi Mawushe Points 10335

Pensez à utiliser le 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ées.

8 votes

Il ne semble pas fonctionner avec les domaines plus récents tels que .london, etc.

0 votes

Et les urls des intranets ?

0 votes

Il ne valide pas les urls avec des underscores.

61voto

Prasanna Pilla Points 201

Voici une méthode que j'ai essayée et trouvée utile,

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

1 votes

Un bon. L'utilisation d'une nouvelle URL(nom) accepte presque tout. Le url.toURI() ; est exactement ce que le développeur recherche - sans utiliser d'autres bibliothèques/frames !

2 votes

Cela ne fonctionnera pas non plus pour les URL malformées telles que http:/google.com. J'ai utilisé UrlValidator de Apache Commons.

2 votes

Celui-ci est vraiment dangereux. Je vois qu'il y a beaucoup d'autres articles avec cet exemple. URL u = new URL(http://google).toURI(); ne lèvera pas d'exception.

8voto

Pumbaa80 Points 27066

J'aimerais poster ceci comme un commentaire à La réponse de Tendayi Mawushe mais je crains qu'il n'y ait pas assez de place ;)

Voici la partie pertinente de l'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à.

3voto

Igal Points 836

Je n'ai aimé aucune des implémentations (parce qu'elles utilisent un Regex qui est une opération coûteuse, ou une bibliothèque qui est une surcharge si vous n'avez besoin que d'une seule méthode), donc j'ai fini par utiliser la classe java.net.URI avec quelques vérifications supplémentaires, et en limitant les protocoles à : http, https, file, ftp, mailto, news, urn.

Et oui, attraper les exceptions peut être une opération coûteuse, mais probablement pas aussi mauvaise 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;
}

2voto

Adam Matan Points 15690

paquet de validateurs :

Il semble y avoir un un paquet sympa de Yonatan Matalon appelé UrlUtil . En citant son API :

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

L'approche de Sun - vérifier l'adresse du réseau

Le site Java de Sun propose connecter la tentative comme une solution pour valider les URLs.

Autres extraits de code regex :

Il y a des tentatives de validation de regex à Site d'Oracle et weberdev.com .

2 votes

Ce code sert à vérifier les liens, ce qui est un problème différent. Cette question porte sur la validité de l'URL, et non sur la possibilité d'établir une connexion avec celle-ci.

0 votes

Cet exemple vise à vérifier si l'URL est disponible, et non si elle est bien formée.

0 votes

D'accord, j'ai ajouté d'autres approches.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X