क्वेरी स्ट्रिंग मापदंडों का जावा URL एन्कोडिंग


710

बोलो मेरे पास एक URL है

http://example.com/query?q=

और मेरे पास उपयोगकर्ता द्वारा दर्ज की गई एक क्वेरी है जैसे:

यादृच्छिक शब्द £ 500 बैंक $

मैं चाहता हूं कि परिणाम ठीक से एन्कोडेड URL हो:

http://example.com/query?q=random%20word%20%A3500%20bank%20%24

इसे प्राप्त करने का सबसे अच्छा तरीका क्या है? मैंने URLEncoderURI / URL ऑब्जेक्ट बनाने और बनाने की कोशिश की, लेकिन उनमें से कोई भी सही नहीं है।


24
आपका क्या मतलब है "उनमें से कोई भी बहुत सही नहीं है"?
मार्क इलियट

2
मैंने URI.create का उपयोग किया है और क्वेरिस्ट्रिंग में + के साथ रिक्त स्थान बदल दिए हैं। जब मैंने क्वेरी स्ट्रिंग्स का चयन किया, तो क्लाइंट साइट पर यह + स्थानों पर वापस परिवर्तित हो गया। मेरे लिए यही काम किया है।
ND27


आप $-प्रतिशत की उम्मीद क्यों करते हैं?
jschnasse

जवाबों:


1150

URLEncoderजाने का रास्ता है। आप केवल एनकोड को ध्यान में रखने की जरूरत है केवल व्यक्ति क्वेरी स्ट्रिंग पैरामीटर नाम और / या मूल्य, नहीं पूरा URL यकीन नहीं क्वेरी स्ट्रिंग पैरामीटर विभाजक वर्ण के लिए &और न ही पैरामीटर नाम-मान विभाजक वर्ण =

String q = "random word £500 bank $";
String url = "https://example.com?q=" + URLEncoder.encode(q, StandardCharsets.UTF_8);

ध्यान दें कि क्वेरी पैरामीटर में रिक्त स्थान का प्रतिनिधित्व किया जाता है +, न कि %20, जो वैध रूप से मान्य है। %20आमतौर पर यूआरआई ही (यूआरआइ-क्वेरी स्ट्रिंग विभाजक वर्ण से पहले भाग में रिक्त स्थान का प्रतिनिधित्व करने के लिए इस्तेमाल किया जा रहा है ?), क्वेरी स्ट्रिंग में नहीं (भाग के बाद ?)।

यह भी ध्यान दें कि तीन encode()विधियाँ हैं। Charsetदूसरे तर्क के रूप में एक और दूसरे तर्क के रूप में एक और Stringजो एक अपवाद को फेंकता है। बिना Charsetतर्क के पदावनत हो जाता है। इसका उपयोग कभी न करें और हमेशा Charsetतर्क निर्दिष्ट करें । जावाडोक भी स्पष्ट रूप से, के रूप में द्वारा अनिवार्य UTF-8 एन्कोडिंग का उपयोग करने की सिफारिश की गई RFC3986 और W3C

अन्य सभी वर्ण असुरक्षित हैं और पहले कुछ एन्कोडिंग योजना का उपयोग करके एक या एक से अधिक बाइट में परिवर्तित हो जाते हैं। फिर प्रत्येक बाइट को 3-वर्ण स्ट्रिंग "% xy" द्वारा दर्शाया जाता है, जहां xy बाइट का दो-अंकीय हेक्साडेसिमल प्रतिनिधित्व है। उपयोग करने के लिए अनुशंसित एन्कोडिंग योजना UTF-8 है । हालांकि, संगतता कारणों के लिए, यदि कोई एन्कोडिंग निर्दिष्ट नहीं है, तो प्लेटफ़ॉर्म के डिफ़ॉल्ट एन्कोडिंग का उपयोग किया जाता है।

यह सभी देखें:


URL में 2 प्रकार के पैरामीटर हो सकते हैं। क्वेरी स्ट्रिंग (इसके बाद?) और पथ पैरामीटर (आमतौर पर URL का ही हिस्सा)। तो, पथ मापदंडों के बारे में क्या। URLEncoder पथ पैरामीटर के लिए भी अंतरिक्ष के लिए + का उत्पादन करता है। वास्तव में यह सिर्फ क्वेरी स्ट्रिंग के अलावा और कुछ नहीं संभालती है। साथ ही, यह व्यवहार नोड js सर्वर के साथ सिंक में नहीं है। इसलिए मेरे लिए यह वर्ग एक बेकार है और इसे बहुत विशिष्ट / विशेष परिदृश्यों के अलावा अन्य उपयोग नहीं किया जा सकता है।
शरदेंदु सिन्हा

2
@sharadendusinha: जैसा कि प्रलेखित और उत्तर दिया गया है, URLEncoderURL-एन्कोडेड क्वेरी मापदंडों के अनुरूप application/x-www-form-urlencodedनियमों के लिए है। पथ श्रेणी इस श्रेणी में फिट नहीं है। आपको इसके बजाय URI एनकोडर की आवश्यकता है।
बालूसी

जैसा कि मैंने भविष्यवाणी की है ... उपयोगकर्ताओं को भ्रम हो रहा है क्योंकि स्पष्ट रूप से समस्या यह है कि लोगों को सिर्फ पैरामीटर मान से अधिक सांकेतिक शब्दों में बदलना चाहिए। इसका एक बहुत ही दुर्लभ मामला है कि आपको केवल एक पैरामीटर मान को एनकोड करना होगा। इसकी वजह से मैंने @sharadendusinha जैसे लोगों की मदद करने के लिए अपना "भ्रमित" विकी उत्तर प्रदान किया।
एडम

1
@WijaySharma: क्योंकि URL-विशिष्ट वर्णों को भी एन्कोड किया जाएगा। आपको केवल तभी करना चाहिए जब आप पूरे URL को दूसरे URL के क्वेरी पैरामीटर के रूप में पास करना चाहते हैं।
BalusC

1
"+,% 20 नहीं" वह है जो मुझे सुनना चाहिए। बहुत बहुत धन्यवाद।
वेटजोश 23

173

मैं उपयोग नहीं करूंगा URLEncoder। गलत तरीके से नाम रखने के अलावा ( URLEncoderURLs से कोई लेना-देना नहीं है), अक्षम्य (यह StringBufferबिल्डर के बजाय उपयोग करता है और कुछ अन्य चीजें करता है जो धीमे हैं) इसका तरीका भी इसे पेंच करना बहुत आसान है।

इसके बजाय मैं स्प्रिंग या कॉमन्स अपाचे का उपयोग URIBuilderया उपयोग करूंगा । इसका कारण आपको क्वेरी पैरामीटर नाम (यानी BalusC का उत्तर ) पैरामीटर मान से भिन्न तरीके से बचना होगा ।org.springframework.web.util.UriUtils.encodeQueryHttpClientq

ऊपर से केवल नीचे की ओर (जो मुझे दर्द से पता चला) यह है कि URL URI का सही उपसमूह नहीं है

नमूना कोड:

import org.apache.http.client.utils.URIBuilder;

URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();

// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24

चूंकि मैं सिर्फ अन्य उत्तरों से जोड़ रहा हूं इसलिए मैंने इसे एक सामुदायिक विकि के रूप में चिह्नित किया है। बेझिझक संपादित करें।


2
URL से इसका कोई लेना-देना क्यों नहीं है?
लुइस

15
@ उपसर्ग: URLEncoderजैसा कि इसके javadoc में कहा application/x-www-form-urlencodedगया है कि HTML युक्ति में वर्णित क्वेरी स्ट्रिंग मापदंडों को सांकेतिक शब्दों में बदलना है : w3.org/TR/html4/interact/… । कुछ उपयोगकर्ता वास्तव में इसे संपूर्ण यूआरआई को एन्कोडिंग के लिए भ्रमित / दुरुपयोग करते हैं, जैसे कि वर्तमान उत्तरदाता ने स्पष्ट रूप से किया था।
बालुसक

8
शॉर्ट URLEncoder में @LuisSep फ़ॉर्म सबमिशन के लिए एन्कोडिंग के लिए है। यह भागने के लिए नहीं है। इसका ठीक उसी तरह से बचना है जो आप अपने वेब पेज में डालने के लिए URL बनाने के लिए उपयोग करते हैं, लेकिन ऐसा ही होता है कि लोग इसका दुरुपयोग करते हैं। URLEncoder का उपयोग करते समय आपको केवल तभी होना चाहिए जब आपका लेखन HTTP क्लाइंट हो (और फिर भी एन्कोडिंग के लिए बेहतर विकल्प हैं)।
एडम गेंट

1
@BalusC " कुछ उपयोगकर्ताओं को वास्तव में भ्रमित करते हैं / इसे पूरे यूआरआई को एन्कोडिंग के लिए दुरुपयोग करते हैं, जैसे कि वर्तमान उत्तरदाता ने स्पष्ट रूप से किया था। " आपने गलत मान लिया। मैंने कभी नहीं कहा कि मैंने इससे पंगा लिया। मैंने बस दूसरों को देखा है जिन्होंने इसे किया है, जिनकी बग को मुझे ठीक करना है। जो हिस्सा मैंने खराब कर दिया है वह यह है कि जावा URL वर्ग बिना किसी कोष्ठक के स्वीकृत होगा लेकिन URI वर्ग नहीं। URL का निर्माण करने के लिए बहुत सारे तरीके हैं और हर कोई आपकी तरह शानदार नहीं है। मैं कहूंगा कि ज्यादातर उपयोगकर्ता जो URLEncoding के लिए SO को देख रहे हैं , वे शायद " उपयोगकर्ता वास्तव में भ्रमित / दुरुपयोग करते हैं " URI से बच रहे हैं।
एडम गेंट

1
प्रश्न इस बारे में नहीं था कि अभी तक आपका उत्तर यही है।
बालुसक

99

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

String urlStr = "http://www.example.com/CEREC® Materials & Accessories/IPS Empress® CAD.pdf"
URL url= new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());

फिर उस उरी को ASCII स्ट्रिंग में बदलें:

urlStr=uri.toASCIIString();

अब आपका url स्ट्रिंग पूरी तरह से एन्कोड हो गया है पहले हमने सरल url एन्कोडिंग किया और फिर हमने इसे ASCII स्ट्रिंग में परिवर्तित कर दिया ताकि यह सुनिश्चित हो सके कि US-ASCII के बाहर कोई वर्ण स्ट्रिंग में शेष नहीं है। यह ठीक वैसा ही है जैसे ब्राउज़र करते हैं।


7
धन्यवाद! यह बेवकूफी है कि आपका समाधान काम करता है, लेकिन अंतर्निहित URL.toURI()नहीं है।
user11153

2
दुर्भाग्य से यह "फ़ाइल: ///" के साथ काम नहीं करता है (उदाहरण के लिए: "फ़ाइल: /// कुछ / निर्देशिका / एक फ़ाइल जिसमें space.html" है); यह "नए URL ()" में MalformedURLException के साथ बम है; इसे ठीक करने के लिए कोई भी विचार?
ZioByte

आपको कुछ इस तरह से करने की आवश्यकता है: स्ट्रिंग urlStr = " कुछ / निर्देशिका / एक फ़ाइल जिसमें space.html हो"; URL url = नया URL (urlStr); URI uri = new URI (url.getProtocol (), url.getUserInfo (), url.getHost (), url.getPort (), url.getPath (), url.getQuery (), url.getRef ()); urlStr = uri.toASCIIString (); urlStr.replace ( "http: //", "file: ///"); मैंने इसका परीक्षण नहीं किया है, लेकिन मुझे लगता है कि यह काम करेगा .... :)
एम अब्दुल सामी

1
@tibi आप बस एससीआई स्ट्रिंग के बजाय इसे स्ट्रिंग में बदलने के लिए uri.toString () विधि का उपयोग कर सकते हैं।
एम अब्दुल समी

1
जिस API के साथ मैं काम कर रहा था +, वह रिक्त स्थान के लिए प्रतिस्थापन को स्वीकार नहीं करता था , लेकिन% 20 को स्वीकार कर लिया, इसलिए इस समाधान ने BalusC से बेहतर काम किया, धन्यवाद!
जूलियन होनमा

35

1
ये एक ही नासमझ से बचने के नियमों से पीड़ित हैं URLEncoder
2rs2ts

3
सुनिश्चित नहीं है कि उन्हें समस्या है। वे "+" या "% 20" से बचने के लिए अंतर करते हैं "" (फॉर्म परम या पथ परम) जो URLEncoderनहीं करता है।
इमैनुएल टौजरी

1
यह मेरे लिए काम करता है मैंने केवल URLEncoder () को UrlEscapers.urlFragmentEscaper () पर कॉल करने के लिए बदल दिया है और यह काम किया है, यह स्पष्ट नहीं है कि क्या मुझे UrlEscapers.urlPathloeeExtaper () के बजाय उपयोग करना चाहिए।
पॉल टेलर

2
वास्तव में यह मेरे लिए काम नहीं करता था क्योंकि URLEncoder के विपरीत यह '+' इसे अकेले नहीं छोड़ता है, सर्वर '+' को अंतरिक्ष के रूप में डिकोड करता है जबकि अगर मैं URLEncoder का उपयोग करता हूं तो% 2B में परिवर्तित हो जाता है और सही ढंग से वापस +
पॉल टेलर में बदल जाता है।

2
लिंक अद्यतन: UrlEscapers
mgaert

6

Apache Http Components पुस्तकालय क्वेरी पारम के निर्माण और एन्कोडिंग के लिए एक स्वच्छ विकल्प प्रदान करता है -

HttpCompords के साथ 4.x उपयोग - URLEncodedUtils

HttpClient 3.x उपयोग के लिए - एनकोडिंग यूटिल


6

यहाँ एक विधि है जिसका उपयोग आप अपने कोड में एक url स्ट्रिंग और पैरामीटर्स के मैप को एक मान्य एन्कोडेड url स्ट्रिंग में क्वेरी पैरामीटर से करने के लिए कर सकते हैं।

String addQueryStringToUrlString(String url, final Map<Object, Object> parameters) throws UnsupportedEncodingException {
    if (parameters == null) {
        return url;
    }

    for (Map.Entry<Object, Object> parameter : parameters.entrySet()) {

        final String encodedKey = URLEncoder.encode(parameter.getKey().toString(), "UTF-8");
        final String encodedValue = URLEncoder.encode(parameter.getValue().toString(), "UTF-8");

        if (!url.contains("?")) {
            url += "?" + encodedKey + "=" + encodedValue;
        } else {
            url += "&" + encodedKey + "=" + encodedValue;
        }
    }

    return url;
}

6
URL url= new URL("http://example.com/query?q=random word £500 bank $");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String correctEncodedURL=uri.toASCIIString(); 
System.out.println(correctEncodedURL);

प्रिंटों

http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$

यहां क्या हो रहा है?

1. संरचनात्मक भागों में URL विभाजित करें। java.net.URL इसके लिए उपयोग करें ।

2. प्रत्येक संरचनात्मक भाग को ठीक से एनकोड करें!

3. पुन्यकोड का उपयोग होस्ट नाम IDN.toASCII(putDomainNameHere)को एनकोड करें !

4.java.net.URI.toASCIIString() प्रतिशत-एनकोड का उपयोग करें , एनएफसी एनकोडेड यूनिकोड - (बेहतर होगा NFKC!)। अधिक जानकारी के लिए देखें: इस URL को ठीक से कैसे एनकोड करें

कुछ मामलों में यह जांचना उचित है कि क्या url पहले से एनकोडेड है । इसके अलावा '+' एन्कोडेड रिक्त स्थान को '% 20' एन्कोडेड रिक्त स्थान से बदलें।

यहां कुछ उदाहरण दिए गए हैं जो ठीक से काम भी करेंगे

{
      "in" : "http://نامه‌ای.com/",
     "out" : "http://xn--mgba3gch31f.com/"
},{
     "in" : "http://www.example.com/‥/foo",
     "out" : "http://www.example.com/%E2%80%A5/foo"
},{
     "in" : "http://search.barnesandnoble.com/booksearch/first book.pdf", 
     "out" : "http://search.barnesandnoble.com/booksearch/first%20book.pdf"
}, {
     "in" : "http://example.com/query?q=random word £500 bank $", 
     "out" : "http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$"
}

समाधान वेब प्लैटफॉर्म टेस्ट द्वारा प्रदान किए गए लगभग 100 टेस्टेस से गुजरता है ।


1

Android में मैं इस कोड का उपयोग करूंगा:

Uri myUI = Uri.parse ("http://example.com/query").buildUpon().appendQueryParameter("q","random word A3500 bank 24").build();

कहाँ Uriहै aandroid.net.Uri


10
यह मानक जावा एपीआई का उपयोग नहीं कर रहा है। तो कृपया प्रयुक्त पुस्तकालय निर्दिष्ट करें।
rmuller

1

मेरे मामले में मुझे बस पूरे यूआरएल को पास करने की जरूरत है और केवल प्रत्येक पैरामीटर के मूल्य को एनकोड करना है। मुझे ऐसा करने के लिए एक सामान्य कोड नहीं मिला (!!) तो मैंने काम करने के लिए यह छोटा तरीका बनाया:

public static String encodeUrl(String url) throws Exception {
    if (url == null || !url.contains("?")) {
        return url;
    }

    List<String> list = new ArrayList<>();
    String rootUrl = url.split("\\?")[0] + "?";
    String paramsUrl = url.replace(rootUrl, "");
    List<String> paramsUrlList = Arrays.asList(paramsUrl.split("&"));
    for (String param : paramsUrlList) {
        if (param.contains("=")) {
            String key = param.split("=")[0];
            String value = param.replace(key + "=", "");
            list.add(key + "=" +  URLEncoder.encode(value, "UTF-8"));
        }
        else {
            list.add(param);
        }
    }

    return rootUrl + StringUtils.join(list, "&");
}

public static String decodeUrl(String url) throws Exception {
    return URLDecoder.decode(url, "UTF-8");
}

यह org.apache.commons.lang3.StringUtils का उपयोग करता है


-2
  1. इस query URLEncoder.encode (क्वेरी, StandardCharsets.UTF_8.displayName) () का उपयोग करें; या यह: URLEncoder.encode (क्वेरी, "UTF-8");
  2. आप follwing कोड का उपयोग कर सकते हैं।

    String encodedUrl1 = UriUtils.encodeQuery(query, "UTF-8");//not change 
    String encodedUrl2 = URLEncoder.encode(query, "UTF-8");//changed
    String encodedUrl3 = URLEncoder.encode(query, StandardCharsets.UTF_8.displayName());//changed
    
    System.out.println("url1 " + encodedUrl1 + "\n" + "url2=" + encodedUrl2 + "\n" + "url3=" + encodedUrl3);

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