ক্যোয়ারী স্ট্রিং পরামিতিগুলির জাভা URL এনকোডিং


710

বলুন আমার একটি ইউআরএল আছে

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

এবং আমি ব্যবহারকারীর দ্বারা প্রবেশ করা একটি প্রশ্ন আছে যেমন:

এলোমেলো শব্দ £ 500 ব্যাংক $

আমি ফলাফলটি সঠিকভাবে এনকোড করা URL হতে চাই:

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

এটি অর্জনের সর্বোত্তম উপায় কী? আমি চেষ্টা করেছি URLEncoderএবং ইউআরআই / ইউআরএল অবজেক্ট তৈরি করেছি তবে এর মধ্যে কোনওটিই ঠিক সঠিকভাবে বেরিয়ে আসেনি।


24
"এগুলির কেউই পুরোপুরি ঠিক বেরিয়ে আসে না" বলতে কী বোঝায়?
মার্ক ইলিয়ট

2
আমি ক্যুরিস্ট্রিংয়ে ইউআর.আর.সি.আরাইট এবং স্পেসগুলি + এর সাথে প্রতিস্থাপন করেছি। ক্লায়েন্ট সাইটে এটি যখন অনুসন্ধানের স্ট্রিংগুলি নির্বাচন করে তখন এটি + স্পেসে ফিরে রূপান্তরিত করে। এটা আমার জন্য কাজ করেছে।
এনডি 27


আপনি কেন আশা করছেন percent শতাংশ-এনকোড হবে?
jschnasse

উত্তর:


1150

URLEncoderযাবার উপায় আপনার কেবল ক্যোরির স্ট্রিং প্যারামিটার বিভাজক অক্ষর বা প্যারামিটারের নাম-মান পৃথককারী চরিত্রটি নয়, পুরো ইউআরএল নয়, কেবল পৃথক ক্যোরিয় স্ট্রিং প্যারামিটারের নাম এবং / অথবা মান এনকোড করতে হবে ।&=

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

নোট করুন যে ক্যোয়ারী প্যারামিটারে ফাঁকা স্থানগুলি বৈধভাবে বৈধ +নয় %20, দ্বারা প্রতিনিধিত্ব করা হয়েছে । %20সাধারণত কোনো URI নিজেই (কোনো URI-কোয়েরি স্ট্রিং বিভাজনকারী চরিত্র সামনে অংশে স্পেস প্রতিনিধিত্ব করতে ব্যবহার করা হয় ?), কোয়েরি স্ট্রিং নেই (পার্ট পর ?)।

এছাড়াও লক্ষ করুন যে এখানে তিনটি encode()পদ্ধতি রয়েছে। একটি Charsetদ্বিতীয় আর্গুমেন্ট হিসাবে এবং অন্যটি Stringদ্বিতীয় তর্ক হিসাবে যা একটি পরীক্ষিত ব্যতিক্রম ছুঁড়ে। Charsetযুক্তিবিহীন একটিকে হ্রাস করা হয়। এটি কখনও ব্যবহার করবেন না এবং সর্বদা Charsetযুক্তি নির্দিষ্ট করুন । Javadoc এমনকি স্পষ্টভাবে, যেমন দ্বারা বাধ্যতামূলক UTF-8 এনকোডিং ব্যবহার করতে পরামর্শ দেওয়া হচ্ছে RFC3986 এবং W3C এর

অন্যান্য সমস্ত অক্ষর অনিরাপদ এবং কিছু এনকোডিং স্কিম ব্যবহার করে প্রথমে এক বা একাধিক বাইটে রূপান্তরিত হয়। তারপরে প্রতিটি বাইটটি 3-অক্ষরযুক্ত স্ট্রিং "% xy" দ্বারা প্রতিনিধিত্ব করা হয়, যেখানে xy বাইটের দুই-অঙ্কের হেক্সাডেসিমাল উপস্থাপনা। ব্যবহার করা বাঞ্ছনীয় এনকোডিং স্কীম হল UTF-8 । যাইহোক, সামঞ্জস্যতার কারণে, যদি কোনও এনকোডিং নির্দিষ্ট না করা থাকে তবে প্ল্যাটফর্মের ডিফল্ট এনকোডিং ব্যবহৃত হয়।

আরো দেখুন:


URL এ 2 ধরণের প্যারামিটার থাকতে পারে। ক্যোরি স্ট্রিং (তারপরে?) এবং পাথ প্যারামিটার (সাধারণত URL এরই অংশ)। সুতরাং, পথের পরামিতিগুলি সম্পর্কে কী। URLEncoder এমনকি পথের পরামিতিগুলির জন্যও স্থানের জন্য উত্পাদন করে। আসলে এটি কোয়েরি স্ট্রিং ব্যতীত অন্য কোনও কিছুই পরিচালনা করে না। এছাড়াও, নোড জেএস সার্ভারের সাথে এই আচরণটি সিঙ্ক হয় না। সুতরাং আমার জন্য এই শ্রেণিটি বর্জ্য এবং খুব নির্দিষ্ট / বিশেষ পরিস্থিতিতে ব্যতীত অন্যটি ব্যবহার করা যায় না।
শারদেন্দু সিনহা

2
@ শরশেন্দুসিনহা: নথিভুক্ত ও উত্তর হিসাবে, URLEncoderইউআরএল-এনকোডেড ক্যোয়ারী প্যারামিটারগুলির application/x-www-form-urlencodedনিয়ম অনুসারে। পাথ প্যারামিটারগুলি এই বিভাগে ফিট করে না। পরিবর্তে আপনার একটি ইউআরআই এনকোডার দরকার।
বালাসসি

যেমনটি আমি পূর্বাভাস দিয়েছিলাম ... ব্যবহারকারীরা বিভ্রান্ত হচ্ছেন কারণ স্পষ্টতই সমস্যা হ'ল মানুষকে কেবলমাত্র প্যারামিটার মানের চেয়ে বেশি এনকোড করা দরকার। এটি খুব বিরল ঘটনা যা আপনার কেবলমাত্র প্যারামিটার মানটি এনকোড করতে হবে। এই কারণেই আমি @ শরদেন্দুসিনহার মতো লোকদের সহায়তার জন্য আমার "বিভ্রান্ত" উইকি উত্তর সরবরাহ করেছি।
অ্যাডাম জেন্ট

1
@ বিজয়শর্মা: কারণ ইউআরএল-নির্দিষ্ট অক্ষরগুলি পাশাপাশি এনকোড হবে। আপনার কেবল তখনই করা উচিত যখন আপনি অন্য URL এর কোয়েরি প্যারামিটার হিসাবে পুরো URLটি পাস করতে চান।
বালাসসি

1
"+,% 20" নয় যা আমার শোনা দরকার। তোমাকে অনেক ধন্যবাদ.
ভেজাজোশ

173

আমি ব্যবহার করব না URLEncoder। ভুলভাবে নামকরণ ছাড়াও ( URLEncoderইউআরএলগুলির সাথে কোনও সম্পর্ক নেই), অযোগ্য (এটি StringBufferবিল্ডারের পরিবর্তে একটি ব্যবহার করে এবং ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে খুঁজে যায়) Its

পরিবর্তে আমি URIBuilderবা স্প্রিংস org.springframework.web.util.UriUtils.encodeQueryবা কমন্স অ্যাপাচি ব্যবহার করবHttpClient । কারণ হিসাবে আপনাকে ক্যোয়ারী প্যারামিটারগুলির নাম (অর্থাত্ বালুসকের উত্তর q) পরামিতি মানের থেকে আলাদাভাবে পালাতে হবে ।

উপরের একমাত্র নেতিবাচক দিক (যা আমি বেদনাদায়কভাবে জানতে পেরেছি) হ'ল ইউআরএলগুলি ইউআরআইয়ের সত্যিকারের উপসেট নয়

কোডের উদাহরণ:

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
ইউআরএলগুলির সাথে এর কোনও সম্পর্ক নেই কেন?
লুইস সেপ্টেম্বর

15
@ লুইস: URLEncoderএর জাভাদোক application/x-www-form-urlencodedযেমন এইচটিএমএল স্পেসে বর্ণনা করেছেন: কোয়েরি স্ট্রিং প্যারামিটারগুলি এনকোড করার উদ্দেশ্যে বলেছেন : w3.org/TR/html4/interact/… । কিছু ব্যবহারকারী সত্যত উত্তর ইউআরআইয়ের মতো পুরো ইউআরআইকে এনকোড করার জন্য এটিকে বিভ্রান্ত / অপব্যবহার করে থাকে current
বালুসসি

8
সংক্ষিপ্ত ইউআরএলএনসি কোডারটি @ লুইসপ ফর্ম জমা দেওয়ার জন্য এনকোডিংয়ের জন্য। এটা পালানোর জন্য নয়। এটি ঠিক একইভাবে পালানো নয় যে আপনি নিজের ওয়েব পৃষ্ঠায় যুক্ত URL গুলি তৈরি করতে ব্যবহার করবেন তবে লোকেরা এটির অপব্যবহার করে এমন যথেষ্ট হবে। আপনার কেবলমাত্র একবার ইউআরএলএনসি কোডার ব্যবহার করা উচিত হ'ল যদি আপনার এইচটিটিপি ক্লায়েন্টটি লেখা হয় (এবং তারপরেও এনকোডিংয়ের জন্য অনেক উচ্চতর বিকল্প রয়েছে)।
অ্যাডাম জেন্ট

1
@ বালুসসি "বর্তমান ব্যবহারকারীরা স্পষ্টতই বলেছেন , পুরো ইউআরআইগুলি এনকোড করার জন্য কিছু ব্যবহারকারী সত্যই এটি বিভ্রান্ত / অপব্যবহার করে। " আপনি ভুল ধরেছেন। আমি কখনও বলিনি যে আমি এটির সাথে খারাপ হয়েছি। আমি অন্যকে দেখেছি যারা এটি করেছে, কে আমার বাগ ঠিক করতে হবে। আমি যে অংশটি স্ক্রু করেছি তা হ'ল জাভা ইউআরএল বর্গটি ইউআরআই ক্লাসটি নয় তবে আনস্কেপড বন্ধনীগুলি গ্রহণ করবে। ইউআরএল তৈরির জন্য অনেকগুলি উপায় রয়েছে এবং প্রত্যেকে আপনার মতো উজ্জ্বল নয়। আমি বলব যে বেশিরভাগ ব্যবহারকারীরা ইউআরএলএনএলকোডিংয়ের জন্য এসও খুঁজছেন সম্ভবত " ব্যবহারকারীরা সত্যই বিভ্রান্ত / অপব্যবহার " ইউআরআই পলায়ন করছে।
অ্যাডাম জেন্ট

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

এখন আপনার ইউআরএল স্ট্রিংটি পুরোপুরি এনকোড হয়েছে প্রথমে আমরা সরল ইউআরএল এনকোডিং করেছি এবং তারপরে আমরা ইউএস-এএসসিআইআই এর বাইরে কোনও অক্ষর স্ট্রিংয়ে না থাকে তা নিশ্চিত করার জন্য এটি এএসসিআইআই স্ট্রিংয়ে রূপান্তরিত করি। এটি ব্রাউজারগুলি ঠিক কীভাবে করে।


7
ধন্যবাদ! এটি নির্বোধ যে আপনার সমাধান কাজ করে, কিন্তু অন্তর্নির্মিত এটি URL.toURI()করে না।
ব্যবহারকারী 11153

2
দুর্ভাগ্যক্রমে এটি "ফাইল: ///" (উদাহরণস্বরূপ: "ফাইল: /// কিছু / ডিরেক্টরি / একটি ফাইল / স্পেসস html সমন্বিত একটি ফাইল") দিয়ে কাজ করছে বলে মনে হয় না; এটি "নতুন ইউআরএল ()" -র সাথে ম্যালফর্মডুরলেক্সেপশন দিয়ে বোমা দেয়; কোন ধারনা কিভাবে এটা ঠিক করতে হবে?
জিওবাইট

আপনাকে এর মতো কিছু করতে হবে: স্ট্রিং urlStr = " কিছু / ডিরেক্টরি / স্পেসগুলি html সমেত একটি ফাইল"; ইউআরএল ইউআরএল = নতুন ইউআরএল (urlStr); ইউআরআই ইউরি = নতুন ইউআরআই (url.getProtocol (), url.getUserInfo (), url.getHost (), url.getPort (), url.getPath (), url.getQuery (), url.getRef ()); urlStr = uri.toASCIIString (); urlStr.replace ( "HTTP: //", "ফাইল: ///"); আমি এটি পরীক্ষা করে দেখিনি, তবে আমি মনে করি এটি কার্যকর হবে .... :)
এম আব্দুল সামি

1
@tibi আপনি Asii স্ট্রিংয়ের পরিবর্তে স্ট্রিংতে রূপান্তর করতে কেবল uri.toString () পদ্ধতি ব্যবহার করতে পারেন।
এম আবদুল সামি

1
আমি যে এপিআইয়ের সাথে কাজ করছিলাম তা +স্পেসগুলির জন্য প্রতিস্থাপনটি গ্রহণ করে নি , তবে% 20 স্বীকার করেছে তাই বালুসসির চেয়ে এই সমাধানটি আরও ভালভাবে কাজ করেছে, ধন্যবাদ!
জুলিয়ান হনমা

35

পেয়ারা 15 এখন সোজা ইউআরএল এসকেপেপারের একটি সেট যুক্ত করেছে ।


1
এগুলি একই বোকা পালানোর নিয়মগুলি ভোগ করে URLEncoder
2rs2ts

3
নিশ্চিত না যে তাদের সমস্যা আছে। তারা উদাহরণস্বরূপ "+" বা "% 20" থেকে "" পালাতে "পার্থক্য URLEncoderকরে যা ফর্ম প্যারাম বা পাথ প্যারাম) নয়।
এমমানুয়েল টাজারি

1
এটি আমার জন্য কাজ করেছে আমি কেবলমাত্র ইউআরএলএনকোডার () -র কাছে কলটি urlEscapers.urlFragmentEscaper () এ কল করার জন্য প্রতিস্থাপন করেছি এবং এটি কাজ করেছে, তার পরিবর্তে আমার urlEscapers.urlPathSementEscaper () ব্যবহার করা উচিত কিনা তা পরিষ্কার নয়।
পল টেলর

2
আসলে এটি আমার পক্ষে কাজ করেনি কারণ ইউআরএলএনসিডারের বিপরীতে এটি '+' এককভাবে এনকোড করে না, সার্ভারটি '+' কে স্থান হিসাবে ডিকোড করে আমি যদি ইউআরএলএনসিডার ব্যবহার করি তবে এটি যদি% 2 বি তে রূপান্তরিত হয় এবং + +
পল টেলরকে

2
লিংক আপডেট: আরলিস্কেপস
এমগের্ট

6

অ্যাপাচি এইচটিপিপি কম্পোনেন্ট লাইব্রেরি কোয়েরি প্যারামগুলি তৈরি এবং এনকোডিংয়ের জন্য একটি ঝরঝরে বিকল্প সরবরাহ করে -

এইচটিটিপি কম্পোনেন্টস 4.x ব্যবহারের সাথে - ইউআরএলএনকোডেড ইউটিস

HttpClient 3.x ব্যবহারের জন্য - EncodingUtil


6

আপনার কোডটিতে ইউআরএল স্ট্রিং এবং প্যারামিটারের মানচিত্রের সাথে ক্যোয়ারী প্যারামিটারগুলি সহ একটি বৈধ এনকোডযুক্ত 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. স্ট্রাকচারাল অংশগুলিতে ইউআরএল বিভক্ত করুন। java.net.URL এটির জন্য ব্যবহার করুন ।

2. প্রতিটি কাঠামোগত অংশ সঠিকভাবে এনকোড করুন!

3. ব্যবহারের IDN.toASCII(putDomainNameHere)জন্য Punycode হোস্টনেম এনকোড!

৪.java.net.URI.toASCIIString() শতাংশ-এনকোডে ব্যবহার করুন , এনএফসি এনকোডেড ইউনিকোড - (এনএফকেসি আরও ভাল হবে)। আরও তথ্যের জন্য দেখুন: কীভাবে এই URL টি সঠিকভাবে এনকোড করা যায়

কিছু ক্ষেত্রে ইউআরএল ইতিমধ্যে এনকোড করা হয়েছে কিনা তা পরীক্ষা করার পরামর্শ দেওয়া হচ্ছে । '%' এনকোডেড স্পেসগুলির সাথে '+' এনকোড করা স্থানগুলিও প্রতিস্থাপন করুন।

এখানে কিছু উদাহরণ রয়েছে যা সঠিকভাবে কাজ করবে

{
      "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

অ্যান্ড্রয়েডে আমি এই কোডটি ব্যবহার করব:

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

কই Uriandroid.net.Uri


10
এটি স্ট্যান্ডার্ড জাভা এপিআই ব্যবহার করছে না। সুতরাং দয়া করে ব্যবহৃত লাইব্রেরি নির্দিষ্ট করুন।
rmuller

1

আমার ক্ষেত্রে আমার কেবল পুরো url পাস এবং প্রতিটি প্যারামিটারের মানটিই এনকোড করা দরকার। আমি এটি করার জন্য একটি সাধারণ কোড পাইনি (!!) সুতরাং কাজটি করার জন্য আমি এই ছোট পদ্ধতিটি তৈরি করেছি:

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. এটি ব্যবহার করুন R URLEncoder.encode (ক্যোয়ারী, স্ট্যান্ডার্ডচারেটস.আউটএফ_8.ডিসপ্লে নাম ()); বা এটি: URLEncoder.encode (ক্যোয়ারী, "ইউটিএফ -8");
  2. আপনি ফলউইং কোডটি ব্যবহার করতে পারেন।

    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
সঠিক না. আপনাকে প্যারামিটারের নাম এবং মান পৃথকভাবে এনকোড করতে হবে। পুরো ক্যোয়ারী স্ট্রিংটি এনকোড করাও পৃথক =এবং &পৃথককারীদের এনকোড করবে , যা সঠিক নয়।
ব্যবহারকারী 207421
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.