जावा में मान्य URL


103

मैं जानना चाहता था कि क्या किसी दिए गए URL को मान्य करने के लिए जावा में कोई मानक API है? मैं यह देखना चाहता हूं कि URL स्ट्रिंग सही है या नहीं, दोनों दिए गए प्रोटोकॉल मान्य हैं और फिर यह जांचने के लिए कि क्या कनेक्शन स्थापित किया जा सकता है।

मैंने HttpURLConnection का उपयोग करने, URL प्रदान करने और इसे कनेक्ट करने का प्रयास किया। मेरी आवश्यकता का पहला भाग पूरा होता दिख रहा है, लेकिन जब मैं HttpURLConnection.connect (), 'java.net.ConnectException: कनेक्शन अस्वीकृत' अपवाद को फेंकने की कोशिश करता हूं।

क्या यह प्रॉक्सी सेटिंग के कारण हो सकता है? मैंने प्रॉक्सी के लिए सिस्टम गुण सेट करने का प्रयास किया लेकिन कोई सफलता नहीं मिली।

मुझे पता है कि मैं क्या गलत कर रहा हूँ।


2
यहाँ 2 प्रश्न प्रतीत होते हैं; URL सत्यापन और एक कनेक्टएक्सैसेप्शन का कारण ढूंढना
बेन जेम्स

चूँकि यह पहली Google हिट है java url validator, इसलिए वास्तव में यहाँ प्रश्न हैं, url को कैसे मान्य किया जाए (स्ट्रिंग को देखने से) और कैसे जांचें कि url उपलब्ध है (http कनेक्शन के माध्यम से, उदाहरण के लिए)।
8:30 बजे

जवाबों:


157

समुदाय के लाभ के लिए, चूंकि
" url सत्यापनकर्ता जावा " की खोज करते समय यह धागा Google पर शीर्ष पर है।


अपवादों को पकड़ना महंगा है, और जब संभव हो तो इससे बचना चाहिए। यदि आप केवल सत्यापित करना चाहते हैं कि आपका स्ट्रिंग एक मान्य 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 मैंने लिंक ठीक कर दिया है। धन्यवाद।
योनातन

18
मैं यह देखने में विफल हूं कि यह मानक एपीआई
b1nary.atr0phy

2
UrlValidator के पास ज्ञात समस्याओं का अपना सेट है। क्या कोई वैकल्पिक पुस्तकालय है जिसे अधिक सक्रिय रूप से बनाए रखा जा रहा है?
एलेक्स एवरबच

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 / समस्याओं के लिए जाँच के कई तरीके हैं। उदाहरण के लिए, यदि आप एक के लिए अपने यूआरएल का उपयोग कर रहे हैं, तो यदि आप एक विकृत यूआरएल है new HttpGet(url), तो आप IllegalArgumentException HttpGet(...)थ्रो को पकड़ सकते हैं । और HttpResponseअगर डेटा प्राप्त करने में कोई समस्या है, तो आप पर सामान भी फेंकता है।
पीटर अज़ताई

2
कनेक्शन केवल होस्ट उपलब्धता को मान्य करता है। URL की वैधता से कोई लेना देना नहीं है।
एंड्री रोडियोनोव

2
MalformedURLException URL के वैध रूप का परीक्षण करने के लिए एक सुरक्षित रणनीति नहीं है। यह उत्तर भ्रामक है।
मार्टिन

1
@ मॉर्टिन: क्या आप विस्तृत कर सकते हैं कि यह सुरक्षित क्यों नहीं है?
जीरो वेनवेल

28
यह बहुत, बहुत महंगा है। OpenConnection / Connect वास्तव में http संसाधन से कनेक्ट करने का प्रयास करेगा। यह उन सबसे महंगे तरीकों में से एक होना चाहिए जो मैंने कभी किसी URL को सत्यापित करने के लिए देखा है।
ग्लेन बेच

33

java.net.URLवर्ग नहीं सब पर यूआरएल मान्य के लिए एक अच्छा तरीका वास्तव में है। MalformedURLExceptionहै निर्माण के दौरान सभी विकृत यूआरएल पर फेंक दिया। URL IOExceptionको पकड़ना java.net.URL#openConnection().connect()या तो मान्य नहीं करता है, केवल वेदर को बताएं या कनेक्शन स्थापित नहीं किया जा सकता है।

इस कोड पर विचार करें:

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

..जब कोई अपवाद नहीं फेंकता।

मैं एक संदर्भ मुक्त व्याकरण का उपयोग करके कार्यान्वित कुछ सत्यापन एपीआई का उपयोग करने की सलाह देता हूं, या बहुत ही सरलीकृत सत्यापन में बस नियमित अभिव्यक्ति का उपयोग करता हूं। हालाँकि मुझे इसके लिए किसी श्रेष्ठ या मानक एपीआई का सुझाव देने की आवश्यकता है, मैंने केवल हाल ही में स्वयं इसकी खोज शुरू की है।

नोट यह सुझाव दिया गया है कि URL#toURI()अपवाद java.net. URISyntaxExceptionको संभालने के संयोजन में URL के सत्यापन की सुविधा हो सकती है। हालांकि, यह विधि केवल बहुत ही सरल मामलों में से एक को पकड़ती है।

निष्कर्ष यह है कि URL को मान्य करने के लिए कोई मानक जावा URL पार्सर नहीं है।


क्या आपको इस समस्या का हल मिल गया है ??
kidd0

@ bi0s.kidd0 कई पुस्तकालय हैं जिनका उपयोग किया जा सकता है, लेकिन हमने अपना रोल करने का फैसला किया। यह पूर्ण नहीं है, लेकिन डोमेन या आईपी (दोनों v4 और v6 दोनों) वाले URL सहित, जिसमें हम रुचि रखते हैं, उसे पार्स कर सकते हैं। github.com/jajja/arachne
मार्टिन

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
ध्यान दें कि यह स्ट्रिंग-> url-> uri सत्यापन योजना रिपोर्ट करती है कि ये परीक्षण मामले वैध हैं: "http: //.com" " com ।" "ftp: // ::: @ example.com" "http: /test.com" "http: test.com" "http: /:" तो जब यह मानक एपीआई है, तो यह लागू होने वाले सत्यापन नियम नहीं हो सकता है क्या उम्मीद है।
डेवके

10

android.webkit.URLUtilAndroid पर उपयोग करें :

URLUtil.isValidUrl(URL_STRING);

नोट: यह केवल URL की प्रारंभिक योजना की जाँच कर रहा है, यह नहीं कि पूरा URL मान्य है।


2
अगर आप एंड्रॉइड एप्लिकेशन पर काम कर रहे हैं तभी।
miva2

8

तृतीय-पक्ष पुस्तकालयों का सहारा लिए बिना जावा में मानकों के अनुसार URL सत्यापन करने का एक तरीका है:

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

URIचेक का निर्माता जो urlएक वैध यूआरआई है, और parseServerAuthorityयह सुनिश्चित करने के लिए कॉल करता है कि यह एक URL (पूर्ण या रिश्तेदार) है और एक URN नहीं है।


अपवाद "यदि इस URI के प्राधिकरण घटक को परिभाषित किया गया है, लेकिन RFC 2396 के अनुसार सर्वर-आधारित प्राधिकरण के रूप में पार्स नहीं किया जा सकता है"। हालांकि यह अन्य प्रस्तावों की तुलना में बहुत बेहतर है, यह एक URL को मान्य नहीं कर सकता है।
मार्टिन

@Martin, आप कंस्ट्रक्टर में सत्यापन के बारे में भूल गए। जैसा कि मैंने लिखा है, URIकंस्ट्रक्टर कॉल और कॉल का संयोजन parseServerAuthorityURL को मान्य करता है, parseServerAuthorityअकेले नहीं ।
dened

1
आप इस पृष्ठ पर ऐसे उदाहरण पा सकते हैं जो आपके सुझाव से गलत रूप से मान्य हैं। प्रलेखन का संदर्भ लें, और यदि यह आपके इच्छित उपयोग के लिए डिज़ाइन नहीं किया गया है, तो कृपया इसका फायदा उठाने के लिए प्रचार न करें।
मार्टिन

@ मर्टिन, क्या आप अधिक विशिष्ट हो सकते हैं? आपकी राय में कौन से उदाहरण इस विधि द्वारा गलत तरीके से मान्य हैं?
dened

1
@ ऐसु हां। दूसरा ://मेजबान के बाद आता है, :पोर्ट नंबर का परिचय देता है, जो वाक्य रचना के अनुसार खाली हो सकता है। //एक खाली खंड के साथ पथ का एक हिस्सा है, जो भी मान्य है। यदि आप अपने ब्राउज़र में यह पता दर्ज करते हैं, तो इसे खोलने की कोशिश की जाएगी (लेकिन सबसे अधिक संभवतः सर्वर नाम नहीं मिलेगा https;))।
dened

2

केवल यह बताना महत्वपूर्ण है कि URL ऑब्जेक्ट सत्यापन और कनेक्शन दोनों को संभालता है। फिर, केवल प्रोटोकॉल जिसके लिए एक हैंडलर sun.net में प्रदान किया गया है। www.protocol अधिकृत हैं ( फ़ाइल , ftp , गोफर , http , https , जार , mailto , netdoc ) वैध हैं। उदाहरण के लिए, ldap प्रोटोकॉल के साथ एक नया URL बनाने का प्रयास करें :

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

आपको ए java.net.MalformedURLException: unknown protocol: ldap

आपको अपने स्वयं के हैंडलर को लागू करने और इसके माध्यम से पंजीकरण करने की आवश्यकता है URL.setURLStreamHandlerFactory()। यदि आप केवल URL सिंटैक्स को मान्य करना चाहते हैं, तो ओवरकिल करना, एक regexp एक सरल समाधान प्रतीत होता है।


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 के लिए काम नहीं करता है जब परीक्षण किया जाता है तो कनेक्शन के लिए उपलब्ध नहीं होता है।
मार्टिन

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
इस regex के साथ कुछ समस्याएं हैं: 1. उपसर्ग के बिना URL अमान्य हैं, (उदाहरण के लिए "stackoverflow.com"), इसमें दो प्रत्ययों के साथ URL भी शामिल हैं यदि वे उपसर्ग (उदाहरण के लिए "amazon.co.uk) को याद कर रहे हैं ")। 2. आईपी हमेशा अमान्य होते हैं (उदाहरण के लिए " 127.0.0.1" ), चाहे वे उपसर्ग का उपयोग करें या न करें। मैं "((http|https|ftp)://)?((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"( स्रोत ) का उपयोग करने का सुझाव देता हूं । इस रेगेक्स का एकमात्र नकारात्मक पहलू यह है कि उदाहरण के लिए "127.0..0.1" और "127.0" मान्य हैं।
नेफा

-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);

सिस्टम गुण हालांकि काम नहीं करता है जैसा कि मैंने पहले उल्लेख किया था।

एक बार फिर धन्यवाद।

सादर, कीया

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.