Jaki jest najlepszy sposób sprawdzenia, czy adres URL jest prawidłowy w Javie?
Jeśli próbujesz zadzwonić new URL(urlString)
i złapać MalformedURLException
, ale wydaje się być zadowolony z wszystkiego, co się zaczyna http://
.
Nie martwię się o ustanowienie połączenia, po prostu ważność. Czy jest na to metoda? Adnotacja w Hibernate Validator? Czy powinienem używać wyrażenia regularnego?
Edycja: niektóre przykłady akceptowanych adresów URL to http://***
i http://my favorite site!
.
java
validation
url
Eric Wilson
źródło
źródło
URL
akceptuje konstruktor?http://***
” działa. „http://my favorite site!
” działa. Nie mogę zmusić go do rzucenia wyjątku (kiedy http: // jest na początku.)Odpowiedzi:
Rozważ użycie klasy Apache Commons UrlValidator
UrlValidator urlValidator = new UrlValidator(); urlValidator.isValid("http://my favorite site!");
Istnieje kilka właściwości, które można ustawić, aby kontrolować, jak to klasa zachowuje się domyślnie
http
,https
iftp
są akceptowane.źródło
local
Itp.new URL(name).toURI()
stało się rozwiązaniem.Oto sposób, który wypróbowałem i okazał się przydatny,
URL u = new URL(name); // this would check for the protocol u.toURI(); // does the extra checking required for validation of URI
źródło
URL u = new URL(http://google).toURI();
nie zgłosi wyjątku.new URL(http://google)
jest ważna ^^ mamy w mojej firmie dużo domeny wewnętrznej takiej jak taChciałbym to opublikować jako komentarz do odpowiedzi Tendayi Mawushe , ale obawiam się, że nie ma wystarczająco dużo miejsca;)
To jest odpowiednia część ze źródła 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;
Stamtąd możesz łatwo zbudować własny walidator.
źródło
Najbardziej „niezawodny” sposób to sprawdzenie dostępności adresu URL:
public boolean isURL(String url) { try { (new java.net.URL(url)).openStream().close(); return true; } catch (Exception ex) { } return false; }
źródło
Moje ulubione podejście, bez zewnętrznych bibliotek:
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) { }
źródło
Sądząc po kodzie źródłowym
URI
,public URL(URL context, String spec, URLStreamHandler handler)
Konstruktor wykonuje więcej walidacji niż inne konstruktory. Możesz spróbować tego, ale YMMV.
źródło
Nie podobała mi się żadna z implementacji (ponieważ używają Regex, która jest kosztowną operacją lub biblioteki, która jest przesadą, jeśli potrzebujesz tylko jednej metody), więc ostatecznie użyłem klasy java.net.URI z niektórymi dodatkowe sprawdzenia i ograniczenie protokołów do: http, https, file, ftp, mailto, news, urn.
I tak, wychwytywanie wyjątków może być kosztowną operacją, ale prawdopodobnie nie tak złą, jak wyrażenia regularne:
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; }
źródło
pakiet walidatora:
Wygląda na to, że Yonatan Matalon stworzył fajny pakiet o nazwie UrlUtil . Cytując jego API:
isValidWebPageAddress(java.lang.String address, boolean validateSyntax, boolean validateExistance) Checks if the given address is a valid web page address.
Podejście firmy Sun - sprawdź adres sieciowy
Witryna Java firmy Sun oferuje próbę połączenia jako rozwiązanie do sprawdzania poprawności adresów URL.
Inne fragmenty kodu wyrażenia regularnego:
Istnieją próby weryfikacji wyrażeń regularnych w witrynie Oracle i weberdev.com .
źródło