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