Làm thế nào để kiểm tra một URL hợp lệ trong Java?


93

Cách tốt nhất để kiểm tra xem một URL có hợp lệ trong Java không?

Nếu cố gắng gọi new URL(urlString)và bắt a MalformedURLException, nhưng nó có vẻ hạnh phúc với bất cứ điều gì bắt đầu bằng http://.

Tôi không quan tâm đến việc thiết lập kết nối, chỉ là tính hợp lệ. Có một phương pháp cho điều này? Chú thích trong Hibernate Validator? Tôi có nên sử dụng regex không?

Chỉnh sửa: Một số ví dụ về URL được chấp nhận là http://***http://my favorite site!.


Làm cách nào để xác định tính hợp lệ nếu bạn không thiết lập kết nối?
Michael Myers

2
Bạn có thể đưa ra một ví dụ về một cái gì đó không phải là một URL hợp lệ mà hàm URLtạo chấp nhận không?
uckelman

1
@mmyers: Tính hợp lệ phải được xác định bởi RFCs 2396 và 2732, những RFC xác định URL là gì.
uckelman

4
@uckelman: Chỉ về bất cứ điều gì. " http://***" hoạt động. " http://my favorite site!" hoạt động. Tôi không thể làm cho nó để ném một ngoại lệ (khi http: // ở đầu.)
Eric Wilson

2
có thể trùng lặp URL xác thực trong Java
JasonB

Câu trả lời:


101

Cân nhắc sử dụng lớp Apache Commons UrlValidator

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

Có một số tính năng mà bạn có thể thiết lập để kiểm soát cách cư xử lớp này, theo mặc định http, httpsftpđược chấp nhận.


7
nó không xuất hiện để làm việc với các lĩnh vực mới như .london vv
VH

còn url mạng nội bộ thì sao?
Puneet

Nó không xác thực các url có dấu gạch dưới.
Udit Kumawat

Không làm việc với các tên miền cấp cao mới và tên miền địa phương, ví dụ như local, vv

Tôi không thể làm cho UrlValidator hoạt động với miền cấp cao nhất của mạng nội bộ wierd của chúng tôi. Những cái phổ biến như .com, .org, và những thứ như vậy hoạt động. Tôi không quan tâm đến việc tạo RegExp cho vấn đề này vì vậy new URL(name).toURI()giải pháp trở thành giải pháp.
Avec

59

Đây là cách tôi đã thử và thấy hữu ích,

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

1
Tốt. Chỉ sử dụng URL (tên) mới chấp nhận hầu hết mọi thứ. Url.toURI (); là chính xác những gì nhà phát triển đang tìm kiếm - mà không cần sử dụng các thư viện / khuôn khổ khác!
justastefan

2
Điều này cũng sẽ không hoạt động đối với các URL không đúng định dạng như http: /google.com. Tôi đã sử dụng UrlValidator từ Apache Commons.
starf

1
Điều này thực sự nguy hiểm. Tôi thấy rằng có rất nhiều bài báo khác có sẵn với ví dụ này. URL u = new URL(http://google).toURI();sẽ không ném một ngoại lệ.
Sonu Oommen

@SonuOommen có lẽ vì new URL(http://google)nó hợp lệ ^^ chúng tôi có nhiều miền nội bộ trong công ty của tôi như thế này
user43968

8

Tôi muốn đăng điều này như một bình luận cho câu trả lời của Tendayi Mawushe , nhưng tôi sợ không có đủ chỗ trống;)

Đây là phần có liên quan từ Apache Commons UrlValidator nguồn :

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

Bạn có thể dễ dàng xây dựng trình xác nhận của riêng mình từ đó.


6

Cách "dễ hiểu" nhất là kiểm tra tính khả dụng của URL:

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

4

Cách tiếp cận yêu thích của tôi, không có thư viện bên ngoài:

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

Đánh giá bằng mã nguồn URI,

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

hàm tạo thực hiện nhiều xác nhận hơn các hàm tạo khác. Bạn có thể thử cái đó, nhưng YMMV.


3

Tôi không thích bất kỳ triển khai nào (vì chúng sử dụng Regex là một hoạt động đắt tiền hoặc một thư viện là quá mức cần thiết nếu bạn chỉ cần một phương thức), vì vậy tôi đã kết thúc bằng cách sử dụng lớp java.net.URI với một số kiểm tra bổ sung và giới hạn các giao thức đối với: http, https, file, ftp, mailto, news, urn.

Và vâng, bắt các ngoại lệ có thể là một hoạt động tốn kém, nhưng có lẽ không tệ như Biểu thức chính quy:

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

gói trình xác thực:

Có vẻ như có một gói tuyệt vời của Yonatan Matalon được gọi là UrlUtil . Trích dẫn API của nó:

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

Cách tiếp cận của Sun - kiểm tra địa chỉ mạng

Trang Java của Sun cung cấp nỗ lực kết nối như một giải pháp để xác thực URL.

Các đoạn mã regex khác:

Đã có nỗ lực xác thực regex trên trang web của Oracleweberdev.com .


1
Mã đó là để kiểm tra các liên kết, đây là một vấn đề khác. Câu hỏi này là về tính hợp lệ của URL, không phải là liệu có thể thiết lập kết nối với nó hay không.
Michael Myers

Ví dụ này là về việc kiểm tra xem URL có sẵn hay không, chứ không phải liệu nó có được định dạng tốt hay không.
uckelman

Đồng ý, bổ sung các cách tiếp cận khác.
Adam Matan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.