Java에서 유효한 URL을 확인하는 방법은 무엇입니까?


93

URL이 Java에서 유효한지 확인하는 가장 좋은 방법은 무엇입니까?

를 호출 new URL(urlString)하고 잡으려고 MalformedURLException했지만으로 시작하는 모든 것에 만족하는 것 같습니다 http://.

나는 연결을 설정하는 것에 대해 걱정하지 않고 단지 타당성을 유지합니다. 이것에 대한 방법이 있습니까? Hibernate Validator의 주석? 정규식을 사용해야합니까?

편집 : 허용되는 URL의 몇 가지 예는 http://***및 http://my favorite site!입니다.


연결을 설정하지 않을 경우 유효성을 어떻게 정의합니까?
— Michael Myers

2
URL생성자가 허용 하는 유효한 URL이 아닌 것의 예를 제공 할 수 있습니까 ?
— uckelman 2010

1
@mmyers : 유효성은 URL이 무엇인지 정의하는 RFC 2396 및 2732에 의해 결정되어야합니다.
— uckelman 2010

4
@uckelman : 거의 모든 것. " http://***"작동합니다. " http://my favorite site!"작동합니다. 예외를 던질 수 없습니다 (http : //가 처음에있을 때)
— Eric Wilson

답변:


101

Apache Commons UrlValidator 클래스 사용 고려

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

이 클래스의 작동 방식을 제어하기 위해 설정할 수있는 몇 가지 속성이 있습니다. 기본적 http으로 https, 및 ftp허용됩니다.


7
.london 등과 같은 최신 도메인에서는 작동하지 않는 것 같습니다.
— VH

인트라넷 URL은 어떻습니까?
— Puneet

밑줄이있는 URL의 유효성을 검사하지 않습니다.
— Udit Kumawat

새 TLD 및 로컬 도메인 이름 (예 : local등)에서 작동하지 않습니다 .

나는 UrlValidator가 우리의 이상한 인트라넷 최상위 도메인에서 작동하도록 할 수 없습니다. .com, .org와 같은 일반적인 것, 그리고 그러한 작품. 이 문제에 대한 RegExp를 만드는 데 관심이 없으므로 new URL(name).toURI()해결책이됩니다.
— Avec

59

내가 시도하고 유용하다고 생각한 방법은 다음과 같습니다.

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
http : /google.com과 같이 형식이 잘못된 URL에서도 작동하지 않습니다. Apache Commons의 UrlValidator를 사용했습니다.
— starf 2014 년

1
이건 정말 위험 해요. 이 예제와 함께 다른 많은 기사가 있다는 것을 알 수 있습니다. URL u = new URL(http://google).toURI();예외가 발생하지 않습니다.
— 소누 Oommen

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

4

외부 라이브러리없이 내가 가장 좋아하는 접근 방식 :

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, file, 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

유효성 검사기 패키지 :

UrlUtil이라는 Yonatan Matalon 의 멋진 패키지 가있는 것 같습니다 . API 인용 :

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

썬의 접근 방식-네트워크 주소 확인

Sun의 Java 사이트는 URL 확인 을위한 솔루션으로 연결 시도를 제공 합니다.

기타 정규식 코드 스 니펫 :

Oracle 사이트 및 weberdev.com 에서 정규식 유효성 검사 시도 가 있습니다 .


1
이 코드는 링크를 확인하기위한 것으로 다른 문제입니다. 이 질문은 URL에 대한 연결을 설정할 수 있는지 여부가 아니라 URL의 유효성에 관한 것입니다.
— Michael Myers

이 예제는 URL이 올바른 형식인지 아닌지 확인하는 것입니다.
— uckelman 2010

동의하고 다른 접근 방식을 추가했습니다.
— Adam Matan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.