จะตรวจสอบ URL ที่ถูกต้องใน Java ได้อย่างไร?


96

วิธีใดเป็นวิธีที่ดีที่สุดในการตรวจสอบว่า URL ถูกต้องใน Java หรือไม่

หากพยายามโทรหาnew URL(urlString)และจับแต่ดูเหมือนว่าจะมีความสุขกับสิ่งที่เริ่มต้นด้วยMalformedURLExceptionhttp://

ฉันไม่ได้กังวลเกี่ยวกับการสร้างการเชื่อมต่อเพียงแค่ความถูกต้อง มีวิธีการนี้หรือไม่? คำอธิบายประกอบใน Hibernate Validator? ฉันควรใช้ regex หรือไม่

แก้ไข: ตัวอย่างบางส่วนของ URL ที่ได้รับการยอมรับและhttp://***http://my favorite site!


คุณจะกำหนดความถูกต้องได้อย่างไรหากคุณไม่ต้องการสร้างการเชื่อมต่อ
Michael Myers

2
คุณสามารถยกตัวอย่างของสิ่งที่ไม่ใช่ URL ที่ถูกต้องที่ผู้URLสร้างยอมรับได้หรือไม่?
uckelman

1
@mmyers: ความถูกต้องควรถูกกำหนดโดย RFCs 2396 และ 2732 ซึ่งกำหนดว่า URL คืออะไร
uckelman

4
@uckelman: เกี่ยวกับอะไรก็ได้ " http://***" ได้ผล " http://my favorite site!" ได้ผล ฉันไม่สามารถโยนข้อยกเว้นได้ (เมื่อ http: // อยู่ที่จุดเริ่มต้น)
Eric Wilson

2
อาจซ้ำกันของValidating URL ใน Java
JasonB

คำตอบ:


102

พิจารณาใช้คลาส Apache Commons UrlValidator

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

มีคุณสมบัติหลาย ๆ อย่างที่คุณสามารถตั้งค่าการควบคุมวิธีการชั้นนี้จะทำงานโดยค่าเริ่มต้นhttp, httpsและftpได้รับการยอมรับ


7
ดูเหมือนว่าจะไม่ทำงานกับโดเมนที่ใหม่กว่าเช่น. London เป็นต้น
VH

แล้วอินทราเน็ต urls ล่ะ
Puneet

ไม่ตรวจสอบความถูกต้องของ URL ด้วยเครื่องหมายขีดล่าง
อุทิศกุ

ไม่ทำงานกับ TLD ใหม่และชื่อโดเมนท้องถิ่นเช่นlocalฯลฯ

ฉันไม่สามารถรับ UrlValidator เพื่อทำงานกับโดเมนระดับบนสุดของอินทราเน็ตที่ใช้ Wi-Fi ได้ คนทั่วไปเช่น. com, .org และงานดังกล่าว ฉันไม่สนใจที่จะสร้าง RegExp สำหรับเรื่องนี้ดังนั้นจึงnew URL(name).toURI()กลายเป็นทางออก
Avec

60

นี่คือวิธีที่ฉันลองและพบว่ามีประโยชน์

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 Oommen

1
@SonuOommen อาจจะnew URL(http://google)เป็นเพราะใช้ได้ ^^ เรามีโดเมนภายในใน บริษัท ของฉันมากมายเช่นนี้
user43968

8

ฉันชอบที่จะโพสต์สิ่งนี้เป็นความคิดเห็นสำหรับคำตอบของ Tendayi Mawusheแต่ฉันกลัวว่าจะมีที่ว่างไม่เพียงพอ;)

นี่คือส่วนที่เกี่ยวข้องจากแหล่งที่มา 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;
}

5

แนวทางที่ฉันชอบโดยไม่มีไลบรารีภายนอก:

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

ฉันไม่ชอบการใช้งานใด ๆ (เพราะพวกเขาใช้ Regex ซึ่งเป็นการดำเนินการที่มีราคาแพงหรือไลบรารีที่เกินความจำเป็นหากคุณต้องการเพียงวิธีเดียว) ดังนั้นฉันจึงใช้คลาส 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

แพ็คเกจตรวจสอบความถูกต้อง:

ดูเหมือนจะเป็นแพคเกจที่ดีโดย Yonatan Matalon เรียก UrlUtil อ้างถึง API:

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

แนวทางของ Sun - ตรวจสอบที่อยู่เครือข่าย

ไซต์ Java ของ Sun เสนอความพยายามในการเชื่อมต่อเป็นโซลูชันสำหรับการตรวจสอบ URL

ข้อมูลโค้ด regex อื่น ๆ :

มีความพยายามตรวจสอบ regex ที่มีเว็บไซต์ของออราเคิลและweberdev.com


1
รหัสนั้นใช้สำหรับตรวจสอบลิงก์ซึ่งเป็นปัญหาที่แตกต่างกัน คำถามนี้เกี่ยวกับความถูกต้องของ URL ไม่ใช่ว่าสามารถสร้างการเชื่อมต่อกับ URL ได้หรือไม่
Michael Myers

ตัวอย่างนี้เกี่ยวกับการตรวจสอบว่า URL พร้อมใช้งานหรือไม่ไม่ใช่ว่ามีรูปแบบที่ถูกต้องหรือไม่
uckelman

ตกลงเพิ่มแนวทางอื่น ๆ
Adam Matan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.