Як перевірити дійсну URL-адресу в Java?


93

Який найкращий спосіб перевірити, чи URL-адреса дійсна в Java?

Якщо спробували зателефонувати new URL(urlString)і зловити MalformedURLException, але, схоже, задоволені усім, що починається з http://.

Мене не турбує встановлення зв’язку, просто дійсність. Чи існує для цього метод? Анотація у програмі перевірки сплячого режиму? Чи слід використовувати регулярний вираз?

Редагувати: Деякі приклади прийнятих URL-адрес - http://***та http://my favorite site!.


Як ви визначаєте дійсність, якщо ви не збираєтеся встановлювати зв’язок?
Майкл Майєрс

2
Чи можете ви навести приклад чогось, що не є допустимою URL-адресою, яку URLприймає конструктор?
uckelman

1
@mmyers: Термін дії повинен визначатись RFC 2396 та 2732, які визначають, що таке URL.
uckelman

4
@uckelman: Майже про все. " http://***" працює. " http://my favorite site!" працює. Я не можу змусити кинути виняток (коли http: // на початку.)
Ерік Вілсон,

2
можливий дублікат
перевіряючої

Відповіді:


101

Подумайте про використання класу Apache Commons UrlValidator

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

Є кілька властивостей , які ви можете встановити для контролю , як цей клас поводиться, за замовчуванням http, httpsі ftpприймаються.


7
схоже, це не працює з новими доменами, такими як .london тощо
VH

як щодо URL-адрес інтрамережі?
Puneet

Він не перевіряє URL-адреси з підкресленнями.
Удіт Кумават,

Не працює з новими доменами верхнього рівня та локальними іменами доменів, наприклад localтощо

Я не зміг змусити UrlValidator працювати з нашим доменом верхнього рівня інтрамережі wierd. Поширені, такі як .com, .org та подібні роботи. Я не зацікавлений у створенні RegExp для цього питання, тому це new URL(name).toURI()стане рішенням.
Avec,

59

Ось спосіб, який я спробував і виявив корисним,

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

1
Хороший. Використання лише нової URL-адреси (імені) приймає майже все. Url.toURI (); саме те, що шукає розробник - без використання інших бібліотек / фреймворків!
justastefan

2
Це також не буде працювати для неправильно сформованих URL-адрес, таких як http: /google.com. Я використовував UrlValidator від Apache Commons.
starf

1
Цей насправді небезпечний. Я бачу, що є багато інших статей із цим прикладом. URL u = new URL(http://google).toURI();не буде кидати виняток.
Sonu

@SonuOommen, можливо, тому new URL(http://google), що дійсний ^^ у нас є багато внутрішнього домену в моїй компанії, як це
user43968

8

Я хотів би опублікувати це як коментар до відповіді Тендая Мавуше , але, боюся, місця недостатньо;)

Це відповідна частина з джерела Apache Commons UrlValidator :

/**
 * 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;

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


6

Найбільш безпечний спосіб - це перевірити наявність URL-адреси:

public boolean isURL(String url) {
  try {
     (new java.net.URL(url)).openStream().close();
     return true;
  } catch (Exception ex) { }
  return false;
}

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) {
}

3

Судячи з вихідного коду URI,

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

конструктор робить більше перевірки, ніж інші конструктори. Ви можете спробувати це, але YMMV.


3

Мені не сподобалася жодна реалізація (оскільки вони використовують регулярний вираз, що є дорогою операцією, або бібліотеку, яка є надмірною, якщо вам потрібен лише один метод), тому я в кінцевому підсумку використав клас java.net.URI з деякими додаткові перевірки та обмеження протоколів: http, https, файл, 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;
}

2

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

Здається, є приємний пакет від Йонатана Маталона під назвою UrlUtil . Цитування його API:

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

Підхід сонця - перевірте мережеву адресу

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

Інші фрагменти коду регулярного виразу:

На сайті Oracle та weberdev.com є спроби перевірки регулярних виразів .


1
Цей код призначений для перевірки посилань, що є іншою проблемою. Це питання стосується дійсності URL-адреси, а не того, чи можна встановити зв’язок із нею.
Майкл Майєрс

Цей приклад стосується перевірки, чи доступна URL-адреса, а не чи правильно вона сформована.
uckelman

Погодився, додав інші підходи.
Адам Матан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.