Java에서 URL 확인


103

주어진 URL의 유효성을 검사하기 위해 Java에 표준 API가 있는지 알고 싶습니까? URL 문자열이 올바른지 즉, 주어진 프로토콜이 유효한지 확인한 다음 연결을 설정할 수 있는지 확인하고 싶습니다.

HttpURLConnection을 사용하여 URL을 제공하고 연결을 시도했습니다. 내 요구 사항의 첫 번째 부분이 충족되는 것 같지만 HttpURLConnection.connect ()를 수행하려고하면 'java.net.ConnectException : Connection rejectd'예외가 발생합니다.

프록시 설정 때문일 수 있습니까? 프록시에 대한 시스템 속성 설정을 시도했지만 성공하지 못했습니다.

내가 뭘 잘못하고 있는지 알려주세요.


2
여기에 2 개의 질문이있는 것 같습니다. URL 유효성 검사 및 ConnectException의 원인 찾기
Ben James

이것이에 대한 첫 번째 Google 히트이기 때문에 java url validator실제로 여기에 질문이 있습니다. URL을 확인하는 방법 (문자열보기에서) 및 URL에 도달 할 수 있는지 확인하는 방법 (예 : http 연결을 통해).
vikingsteve

답변:


157

커뮤니티의 이익을 위해이 스레드는
" url validator java "를 검색 할 때 Google에서 최상위에 있습니다.


예외 포착은 비용이 많이 들고 가능하면 피해야합니다. String이 유효한 URL인지 확인하려는 경우 Apache Commons Validator 프로젝트 의 UrlValidator 클래스를 사용할 수 있습니다 .

예를 들면 :

String[] schemes = {"http","https"}; // DEFAULT schemes = "http", "https", "ftp"
UrlValidator urlValidator = new UrlValidator(schemes);
if (urlValidator.isValid("ftp://foo.bar.com/")) {
   System.out.println("URL is valid");
} else {
   System.out.println("URL is invalid");
}

37
해당 URLValidator 클래스는 사용되지 않음으로 표시됩니다. 권장되는 URLValidator는 다음 루틴 패키지에 있습니다. commons.apache.org/validator/apidocs/org/apache/commons/…
Spektr

6
@Spektr 링크를 수정했습니다. 감사.
Yonatan 2011 년

18
나는이 얼마나보고 실패 표준 API
b1nary.atr0phy가

2
UrlValidator에는 자체 알려진 문제 집합이 있습니다. 보다 적극적으로 유지되고있는 대체 라이브러리가 있습니까?
Alex Averbuch 2013-08-13

9
@AlexAverbuch : UrlValidator의 문제에 대해 설명해 주시겠습니까? 그들이 존재한다고 말하고 그들이 무엇인지 말하지 않는 것은별로 도움이되지 않습니다.
cdmckay

33

URL개체와 개체를 모두 만들어야 URLConnection합니다. 다음 코드는 URL 형식과 연결을 설정할 수 있는지 여부를 테스트합니다.

try {
    URL url = new URL("http://www.yoursite.com/");
    URLConnection conn = url.openConnection();
    conn.connect();
} catch (MalformedURLException e) {
    // the URL is not in a valid form
} catch (IOException e) {
    // the connection couldn't be established
}

잘못된 URL / 문제를 확인하는 방법에는 여러 가지가 있습니다. 예를 들어에 대한 URL을 사용하는 경우 잘못된 형식의 URL이 있으면 throws를 new HttpGet(url)잡을 수 있습니다 IllegalArgumentException HttpGet(...). 그리고 HttpResponse데이터를 얻는 데 문제가 있으면 당신에게도 물건을 던질 것입니다.
Peter Ajtai

2
연결은 호스트 가용성 만 확인합니다. URL의 유효성과 관련이 없습니다.
Andrey Rodionov 2012

2
MalformedURLException은 유효한 URL 형식을 테스트하기위한 안전한 전략이 아닙니다. 이 대답은 잘못된 것입니다.
Martin

1
@Martin : 안전하지 않은지 설명해 주 시겠습니까?
Jeroen Vannevel 2014 년

28
이것은 매우, 매우 비쌉니다. openConnection / connect는 실제로 http 리소스에 연결을 시도합니다. 이것은 URL을 확인하기 위해 내가 본 것 중 가장 비용이 많이 드는 방법 중 하나입니다.
Glenn Bech 2014 년

33

java.net.URL클래스는 모든에서 실제로 URL을 확인하는 좋은 방법입니다. MalformedURLException되어 있지 건설 기간 동안 모든 잘못된 URL을 발생합니다. 캐칭 IOExceptionjava.net.URL#openConnection().connect()URL의 유효성을 검사하지 않으며 연결을 설정할 수 있는지 여부 만 알려줍니다.

다음 코드를 고려하십시오.

    try {
        new URL("http://.com");
        new URL("http://com.");
        new URL("http:// ");
        new URL("ftp://::::@example.com");
    } catch (MalformedURLException malformedURLException) {
        malformedURLException.printStackTrace();
    }

.. 예외를 발생시키지 않습니다.

컨텍스트 프리 문법을 사용하여 구현 된 일부 유효성 검사 API를 사용하거나 매우 단순화 된 유효성 검사에서는 정규식을 사용하는 것이 좋습니다. 그러나이를 위해 우수한 또는 표준 API를 제안 할 누군가가 필요합니다. 저는 최근에야 직접 검색을 시작했습니다.

참고URL#toURI() 예외 처리와 함께 java.net. URISyntaxExceptionURL 유효성 검사를 용이하게 할 수 있다고 제안되었습니다 . 그러나이 방법은 위의 매우 간단한 경우 중 하나만 포착합니다.

결론은 URL의 유효성을 검사하는 표준 Java URL 파서가 없다는 것입니다.


이 문제에 대한 해결책을 찾았습니까 ??
kidd0 2014 년

@ bi0s.kidd0 사용할 수있는 라이브러리가 여러 개 있지만 자체적으로 롤링하기로 결정했습니다. 완전하지는 않지만 도메인 또는 IP (v4 및 v6 모두)를 포함하는 URL을 포함하여 관심있는 내용을 구문 분석 할 수 있습니다. github.com/jajja/arachne
Martin

15

표준 API 사용 하여 문자열을 URL개체에 전달한 다음 개체로 변환 URI합니다. 이것은 RFC2396 표준에 따라 URL의 유효성을 정확하게 결정합니다.

예:

public boolean isValidURL(String url) {

    try {
        new URL(url).toURI();
    } catch (MalformedURLException | URISyntaxException e) {
        return false;
    }

    return true;
}

5
이 string-> url-> uri 유효성 검사 체계는 "http : //.com" " com ." 테스트 사례가 유효 함을보고합니다 . "ftp : // :::: @ example.com" "http : /test.com" "http : test.com" "http : / :"따라서 이것이 표준 API이지만 적용되는 유효성 검사 규칙은 기대하는 것.
DaveK 2013-10-28

10

를 사용하여 android.webkit.URLUtil안드로이드에 :

URLUtil.isValidUrl(URL_STRING);

참고 : 전체 URL이 유효한 것이 아니라 URL의 초기 스키마를 확인하는 것입니다.


2
물론 안드로이드 응용 프로그램에서 작업하는 경우에만.
miva2

8

타사 라이브러리에 의존하지 않고 Java의 표준에 따라 URL 유효성 검사를 수행하는 방법이 있습니다.

boolean isValidURL(String url) {
  try {
    new URI(url).parseServerAuthority();
    return true;
  } catch (URISyntaxException e) {
    return false;
  }
}

유효한 URI 인 URI검사 생성자 및 URN이 아닌 URL (절대 또는 상대)인지 확인하는 url호출 parseServerAuthority입니다.


"이 URI의 권한 구성 요소가 정의되었지만 RFC 2396에 따라 서버 기반 권한으로 구문 분석 할 수없는 경우"예외가 발생합니다. 이것은 대부분의 다른 제안보다 훨씬 낫지 만 URL을 확인할 수는 없습니다.
Martin

@Martin, 생성자의 유효성 검사를 잊었습니다. 내가 쓴 것처럼 URI생성자 호출과 호출 의 조합은 parseServerAuthorityURL을 parseServerAuthority단독으로 확인하는 것이 아니라 유효성을 검사합니다 .
dened

1
이 페이지에서 귀하의 제안으로 잘못 검증 된 예를 찾을 수 있습니다. 문서를 참조하고 의도 한 용도로 설계되지 않은 경우 악용하도록 홍보하지 마십시오.
Martin

@Martin, 더 구체적으로 말할 수 있습니까? 이 방법으로 잘못 검증 된 예는 무엇입니까?
2019 년

1
@Asu 네. 두 번째 ://는 호스트 뒤에 오며 :구문에 따라 비어있을 수있는 포트 번호를 소개합니다. //빈 세그먼트가있는 경로의 일부이며 유효합니다. 이 주소를 브라우저에 입력하면 해당 주소를 열려고합니다 (하지만 대부분의 경우 https; 이라는 서버를 찾지 못함 ).
dened

2

URL 개체가 유효성 검사와 연결을 모두 처리한다는 점을 지적하는 것이 중요합니다. 그러면 sun.net.www.protocol 에서 핸들러가 제공된 프로토콜 ( file , ftp , gopher , http , https , jar , mailto , netdoc ) 만 유효한 프로토콜 입니다. 예를 들어, ldap 프로토콜 을 사용하여 새 URL을 만들어보십시오 .

new URL("ldap://myhost:389")

당신은 java.net.MalformedURLException: unknown protocol: ldap.

자체 처리기를 구현하고 URL.setURLStreamHandlerFactory(). URL 구문의 유효성을 검사하고 싶다면 정규 표현식이 더 간단한 솔루션 인 것 같습니다.


1

시스템 속성으로 올바른 프록시를 사용하고 있습니까?

또한 1.5 또는 1.6을 사용하는 경우 java.net.Proxy 인스턴스를 openConnection () 메서드에 전달할 수 있습니다. 이것은 더 우아한 imo입니다.

//Proxy instance, proxy ip = 10.0.0.1 with port 8080
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.0.0.1", 8080));
conn = new URL(urlString).openConnection(proxy);

왜 이것이 우아하거나 정확할까요? 작동 할 때 값 비싼 리소스를 사용하고 테스트시 연결에 사용할 수없는 올바른 URL에 대해 작동하지 않습니다.
Martin

0

가장 좋은 답변은 @ b1nary.atr0phy 사용자의 것입니다. 어떻게 든 b1nay.atr0phy 응답의 방법을 정규식과 결합하여 가능한 모든 경우를 처리하는 것이 좋습니다.

public static final URL validateURL(String url, Logger logger) {

        URL u = null;
        try {  
            Pattern regex = Pattern.compile("(?i)^(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?$");
            Matcher matcher = regex.matcher(url);
            if(!matcher.find()) {
                throw new URISyntaxException(url, "La url no está formada correctamente.");
            }
            u = new URL(url);  
            u.toURI(); 
        } catch (MalformedURLException e) {  
            logger.error("La url no está formada correctamente.");
        } catch (URISyntaxException e) {  
            logger.error("La url no está formada correctamente.");  
        }  

        return u;  

    }

1
이 정규식에는 몇 가지 문제가 있습니다. 1. 접두사가없는 URL은 유효하지 않습니다 (예 : "stackoverflow.com"). 접두사가없는 경우 접미사가 2 개인 URL (예 : "amazon.co.uk)도 여기에 포함됩니다. "). 2. IP는 접두사 사용 여부에 관계없이 항상 유효하지 않습니다 (예 : " 127.0.0.1" ). "((http|https|ftp)://)?((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"( source )를 사용하는 것이 좋습니다 . 이 정규식의 유일한 단점은 "127.0..0.1"및 "127.0"이 유효하다는 것입니다.
Neph

-2

감사. NickDK에서 제안한대로 프록시를 전달하여 URL 연결을 열면 정상적으로 작동합니다.

//Proxy instance, proxy ip = 10.0.0.1 with port 8080
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.0.0.1", 8080));
conn = new URL(urlString).openConnection(proxy);

그러나 시스템 속성은 앞서 언급 한대로 작동하지 않습니다.

다시 한 번 감사드립니다.

감사합니다, Keya

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.