Как проверить действительный URL в Java? - PullRequest
82 голосов
/ 09 февраля 2010

Каков наилучший способ проверить, является ли URL действительным в Java?

Если попытаться дозвониться до new URL(urlString) и поймать MalformedURLException, но, похоже, доволен всем, что начинается с http://.

Я не беспокоюсь об установлении соединения, просто действительность. Есть ли способ для этого? Аннотация в Hibernate Validator? Должен ли я использовать регулярное выражение?

Редактировать: Некоторые примеры допустимых URL-адресов: http://*** и http://my favorite site!.

Ответы [ 8 ]

92 голосов
/ 09 февраля 2010

Рассмотрите возможность использования класса Apache Commons UrlValidator

UrlValidator urlValidator = new UrlValidator();
urlValidator.isValid("http://my favorite site!");

Существует несколько свойств, которые можно установить для управления поведением этого класса, по умолчанию принимаются http, https и ftp.

55 голосов
/ 19 апреля 2011

Вот способ, который я попробовал и нашел полезным,

URL u = new URL(name); // this would check for the protocol
u.toURI(); // does the extra checking required for validation of URI 
6 голосов
/ 19 декабря 2012

Я хотел бы опубликовать это как комментарий к Ответ Тендай Мавуше , но, боюсь, не хватает места;)

Это соответствующая часть из 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;

Вы можете легко создать свой собственный валидатор.

4 голосов
/ 07 февраля 2019

Самый «надежный» способ - проверить наличие URL:

public boolean isURL(String url) {
  try {
     (new java.net.URL(url)).openStream().close();
     return true;
  } catch (Exception ex) { }
  return false;
}
4 голосов
/ 18 ноября 2013

Мой любимый подход, без внешних библиотек:

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) {
}
3 голосов
/ 09 февраля 2010

Судя по исходному коду для URI,

public URL(URL context, String spec, URLStreamHandler handler)

конструктор делает больше проверки, чем другие конструкторы. Вы можете попробовать это, но YMMV.

3 голосов
/ 09 февраля 2010

пакет валидатора:

Похоже, что хороший пакет от Йонатана Маталона под названием UrlUtil . Цитирую его API:

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

Подход Sun - проверьте сетевой адрес

Java-сайт Sun предлагает попытку подключения в качестве решения для проверки URL.

Другие фрагменты кода регулярного выражения:

Есть попытки проверки регулярных выражений на сайте Oracle и weberdev.com .

2 голосов
/ 25 июня 2013

Мне не понравилась ни одна из реализаций (потому что они используют 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...