2010-09-22 11 views
16

के लिए जाँच करने के लिए मैं इस परिदृश्य है:उचित तरीके से यूआरएल समानता

URL u1 = new URL("http://www.yahoo.com/"); 
URL u2 = new URL("http://www.yahoo.com"); 

if (u1.equals(u2)) { 
    System.out.println("yes"); 
} 
if (u1.toURI().equals(u2.toURI())) { 
    System.out.println("uri equality"); 
} 
if (u1.toExternalForm().equals(u2.toExternalForm())) { 
    System.out.println("external form equality"); 
} 
if (u1.toURI().normalize().equals(u2.toURI().normalize())) { 
    System.out.println("uri normalized equality"); 
} 

इन चेकों में से कोई भी सफल रहे हैं। केवल पथ अलग है: u1 का पथ "/" है जबकि u2 का पथ "" है। क्या ये यूआरएल एक ही संसाधन को इंगित कर रहे हैं और कनेक्शन खोलने के बिना ऐसी कोई चीज़ जांचने का कोई तरीका है? क्या मैं यूआरएल के बारे में कुछ मौलिक समझ रहा हूं?

संपादित करें मुझे यह कहना चाहिए कि एक गैर हैकी चेक वांछित है। क्या यह कहना उचित है कि खाली पथ == /? मैं 2007 JavaOne से कोड

उत्तर

21

इस तरह का नहीं की उम्मीद कर रहा था:

दूसरा पहेली, जिसे उपयुक्त शीर्षक "समूह की अधिक खुशियाँ" उपयोगकर्ता HashMap कुंजी है कि मिलकर बनता है या कई यूआरएल वस्तुओं को बनाने के है। फिर, अधिकांश दर्शक सही जवाब का अनुमान लगाने में असमर्थ थे।

दर्शकों की यहां महत्वपूर्ण बात यह है कि यूआरएल ऑब्जेक्ट की बराबर() विधि, टूटी हुई है। इस मामले में, दो यूआरएल ऑब्जेक्ट बराबर होते हैं यदि वे एक ही आईपी पते और बंदरगाह को हल करते हैं, न कि अगर उनके बराबर तार हैं। हालांकि, ब्लोच और पुग एक और अधिक गंभीर एचिल्स 'हेल इंगित करते हैं: समानता व्यवहार अलग-अलग होता है कि आप नेटवर्क से कनेक्ट हैं, जहां वर्चुअल पते उसी मेजबान को हल कर सकते हैं, या यदि आप नेट पर नहीं हैं, जहां संकल्प एक अवरुद्ध ऑपरेशन है। इसलिए, जहां तक ​​सबक सीखे, वे अनुशंसा करते हैं:

यूआरएल का उपयोग न करें; के बजाय यूआरआई का उपयोग करें। यूआरआई पते या बंदरगाहों की तुलना करने का कोई प्रयास नहीं करता है। इसके अतिरिक्त, URL को सेट तत्व या मानचित्र कुंजी के रूप में उपयोग न करें।
एपीआई डिजाइनरों के लिए, बराबर() विधि पर्यावरण पर निर्भर नहीं होना चाहिए। उदाहरण के लिए, इस मामले में, यदि कंप्यूटर इंटरनेट बनाम स्टैंडअलोन से जुड़ा हुआ है तो समानता नहीं बदली जानी चाहिए।


यूआरआई से प्रलेखन के बराबर होती है:

दो श्रेणीबद्ध यूआरआई के लिए बराबर पर विचार किया जाएगा, उनके रास्ते बराबर होना चाहिए और उनके प्रश्नों या तो दोनों अपरिभाषित हो या फिर बराबर होना चाहिए।

आपके मामले में, दो पथ अलग हैं। एक "/" दूसरा है ""।


यूआरआई आरएफसी §6.2.3 के अनुसार:

क्रियान्वयन उपयोग योजना-विशिष्ट नियमों को, आगे की प्रक्रिया के कीमत पर, मिथ्या नकारात्मक की संभावना को कम करने के लिए कर सकते हैं।उदाहरण के लिए, क्योंकि "http" योजना प्राधिकरण घटक का उपयोग करती है, उसके पास "80" का डिफ़ॉल्ट पोर्ट है, और "/" के बराबर होने के लिए एक खाली पथ परिभाषित करता है, निम्नलिखित चार यूआरआई समकक्ष हैं:

http://example.com 
http://example.com/ 
http://example.com:/ 
http://example.com:80/ 

ऐसा लगता है कि यह कार्यान्वयन योजना-विशिष्ट नियमों का उपयोग नहीं करता है।


संसाधन:

+3

उपयोग कर सकते हैं ... इस सवाल पर सभी उत्तर नहीं देता। – Zarel

+0

दिलचस्प .. लेकिन फिर टूरू() परीक्षण सफल होगा अगर वे वास्तव में बराबर थे। –

+0

@ एसबी, अधिक आरएफसी और अधिक दस्तावेज़ीकरण के साथ अद्यतन :) –

2

सच पूछिये तो वे नहीं क्षेत्रों में काम कर रहे हैं अल। वैकल्पिक पिछला स्लैश (/) केवल एक आम उपयोग है, लेकिन जरूरी नहीं है। आप के लिए

http://www.yahoo.com/foo/ 

विभिन्न पृष्ठों को प्रदर्शित कर सकता है और के लिए

http://www.yahoo.com/foo 

यह भी एक आपके द्वारा दी गई मेरा मानना ​​है कि HTTP हेडर कि स्लैश को छोड़ सकता है के लिए संभव है।

+0

सही लेकिन क्या तर्क हो सकता है जो www.yahoo.com और www.yahoo.com/ को बदलता है? –

+7

'example.com/foo /' और 'example.com/foo' अलग हैं, हां, लेकिन' example.com' और 'example.com /' बिल्कुल वही हैं। – Zarel

0

आप हमेशा पथ.equals-method

पूर्व के साथ सापेक्ष URL की तुलना कर सकते हैं।

Paths.get("/user/login").equals(Paths.get("/user/login/"))) 

उपज सच

तुम भी startsWith/endsWith-तरीकों

+0

क्या यह यूरी के लिए भी काम करेगा ?? – SAVVY

+0

पथों की तरह कोई कक्षा नहीं है – SAVVY

संबंधित मुद्दे