Bagaimana cara memeriksa URL yang valid di Java?

96

Apa cara terbaik untuk memeriksa apakah URL valid di Java?

Jika mencoba menelepon new URL(urlString)dan menangkap MalformedURLException, tetapi tampaknya senang dengan apa pun yang dimulai dengan http://.

Saya tidak peduli tentang membuat koneksi, hanya validitas. Apakah ada metode untuk ini? Anotasi dalam Hibernate Validator? Haruskah saya menggunakan regex?

Edit: Beberapa contoh URL yang diterima adalah http://***dan http://my favorite site!.

Eric Wilson
sumber
Bagaimana Anda mendefinisikan validitas jika Anda tidak akan membuat koneksi?
Michael Myers
2
Dapatkah Anda memberikan contoh sesuatu yang bukan URL valid yang URLditerima konstruktor?
uckelman
1
@mmyers: Validitas harus ditentukan oleh RFC 2396 dan 2732, yang menentukan apa itu URL.
uckelman
4
@uckelman: Apa saja. " http://***" berhasil. " http://my favorite site!" berhasil. Saya tidak bisa membuatnya mengeluarkan pengecualian (ketika http: // ada di awal.)
Eric Wilson
2
kemungkinan duplikat dari Memvalidasi URL di Java
JasonB

Jawaban:

102

Pertimbangkan untuk menggunakan kelas UrlValidator Apache Commons

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

Ada beberapa properti yang dapat diatur untuk mengontrol bagaimana ini berperilaku kelas, secara default http, httpsdan ftpditerima.

Tendayi Mawushe
sumber
7
tampaknya tidak bekerja dengan domain yang lebih baru seperti .london dll
VH
bagaimana dengan url intranet?
Puneet
Itu tidak memvalidasi url dengan garis bawah.
Udit Kumawat
Tidak berfungsi dengan TLD baru dan nama domain lokal, misalnya local, dll.
Saya tidak bisa mendapatkan UrlValidator untuk bekerja dengan domain tingkat atas intranet aneh kami. Yang umum seperti .com, .org, dan karya semacam itu. Saya tidak tertarik membuat RegExp untuk masalah ini jadi new URL(name).toURI()solusinya.
Avec
60

Inilah cara saya mencoba dan merasa berguna,

URL u = new URL(name); // this would check for the protocol
u.toURI(); // does the extra checking required for validation of URI 
Prasanna Pilla
sumber
1
Bagus. Menggunakan URL baru (nama) menerima hampir semua hal. Url.toURI (); persis seperti yang dicari pengembang - tanpa menggunakan pustaka / kerangka kerja lain!
justastefan
2
Ini juga tidak akan berfungsi untuk URL dengan format yang salah seperti http: /google.com. Saya menggunakan UrlValidator dari Apache Commons.
Starf
1
Yang ini sangat berbahaya. Saya melihat ada banyak artikel lain di luar sana dengan contoh ini. URL u = new URL(http://google).toURI();tidak akan membuat pengecualian.
Sonu Oommen
1
@SonuOommen mungkin karena new URL(http://google)valid ^^ kami memiliki banyak domain internal di perusahaan saya seperti ini
user43968
8

Saya ingin memposting ini sebagai komentar atas jawaban Tendayi Mawushe , tetapi saya khawatir tidak ada cukup ruang;)

Ini adalah bagian yang relevan dari Apache Commons UrlValidator sumber :

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

Anda dapat dengan mudah membuat validator Anda sendiri dari sana.

pengguna123444555621
sumber
6

Cara paling "sangat mudah" adalah dengan memeriksa ketersediaan URL:

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

Pendekatan favorit saya, tanpa perpustakaan eksternal:

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

Dilihat dari kode sumbernya URI, file

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

konstruktor melakukan lebih banyak validasi daripada konstruktor lainnya. Anda mungkin mencoba yang itu, tetapi YMMV.

uckelman
sumber
3

Saya tidak menyukai salah satu implementasi (karena mereka menggunakan Regex yang merupakan operasi mahal, atau perpustakaan yang berlebihan jika Anda hanya membutuhkan satu metode), jadi saya akhirnya menggunakan kelas java.net.URI dengan beberapa pemeriksaan ekstra, dan membatasi protokol ke: http, https, file, ftp, mailto, news, urn.

Dan ya, menangkap pengecualian bisa menjadi operasi yang mahal, tapi mungkin tidak seburuk Ekspresi Reguler:

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

paket validator:

Sepertinya ada paket bagus dari Yonatan Matalon yang disebut UrlUtil . Mengutip API-nya:

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

Pendekatan Sun - periksa alamat jaringan

Situs Java Sun menawarkan upaya koneksi sebagai solusi untuk memvalidasi URL.

Potongan kode regex lainnya:

Ada upaya validasi regex di situs Oracle dan weberdev.com .

Adam Matan
sumber
1
Kode itu untuk memeriksa tautan, yang merupakan masalah lain. Pertanyaan ini tentang validitas URL, bukan apakah koneksi dapat dibuat ke sana.
Michael Myers
Contoh ini tentang memeriksa apakah URL tersedia, bukan dalam format yang baik.
uckelman
Setuju, ditambahkan pendekatan lain.
Adam Matan