URLEncoder স্থান অক্ষর অনুবাদ করতে সক্ষম নয় able


179

আমি আশা করছি

System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));

আউটপুট থেকে:

Hello%20World

(20 স্থানের জন্য ASCII হেক্স কোড)

তবে আমি যা পাই তা হ'ল:

Hello+World

আমি কি ভুল পদ্ধতি ব্যবহার করছি? আমার সঠিক পদ্ধতিটি ব্যবহার করা উচিত?


3
শ্রেণীর নামটি প্রকৃতপক্ষে বিভ্রান্তিকর এবং অনেক লোক এটিকে ভুলভাবে ব্যবহার করেছে। তবে তারা এটি লক্ষ্য করে না, কারণ যখন ইউআরএলডিকোডার প্রয়োগ করা হয় তখন মূল মানটি পুনরুদ্ধার করা হয়, সুতরাং + বা% 20 তাদের পক্ষে সত্যিই গুরুত্বপূর্ণ নয়।
অপরিবর্তনীয়

উত্তর:


227

এটি প্রত্যাশার মতো আচরণ করে। URLEncoderকার্যকরী এইচটিএমএল ফর্ম কিভাবে সঙ্কেতাক্ষরে লিখা URL গুলি জন্য HTML উল্লেখ।

জাভাডোকস থেকে :

এই শ্রেণিতে স্ট্রিংটিকে অ্যাপ্লিকেশন / x-www-form-urlencoded MIME ফর্ম্যাটে রূপান্তর করার জন্য স্ট্যাটিক পদ্ধতি রয়েছে।

এবং এইচটিএমএল স্পেসিফিকেশন থেকে :

আবেদন / এক্স-WWW-ফর্ম-urlencoded

এই বিষয়বস্তুর প্রকারের সাথে জমা দেওয়া ফর্মগুলি অবশ্যই নীচে এনকোড করা উচিত:

  1. নাম এবং মানগুলি রক্ষা পায়। স্পেস অক্ষরগুলি `+ 'দ্বারা প্রতিস্থাপিত হয়েছে

আপনাকে এটি প্রতিস্থাপন করতে হবে, যেমন:

System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));

19
ভাল এটি আসলে একটি উত্তর, প্রতিস্থাপনের পরিবর্তে কোনও জাভা গ্রন্থাগার বা টাস্কটি সম্পাদনের জন্য কোনও ফাংশন / নেই?
co2f2e

5
প্লাস চিহ্নটি t.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("\\+", "%20"));
জর্জ

26
@ কোংলিউ এটি ভুল rect আপনি সম্ভবত রিপ্লেক্সএল () যা রিজেক্সের সাথে কাজ করে - বদলে () সরল অক্ষরের ক্রম প্রতিস্থাপনের কথা ভাবছেন।
কাপউনটাই 30

12
হ্যাঁ @ কংলিইউ ভাল উপায় হ'ল: ইউআরএলএনসিওডার.ইনকোড ("মাইআর্ল", "ইউটিএফ -8") replace
eento

9
@ ক্লিন্টইস্টউড এই উত্তরটি java.net.URLEncoder ব্যবহারের জন্য উত্সাহ দেয় যা মূলত যা জিজ্ঞাসা করা হয়েছিল তার কাজ নয়। এবং সুতরাং এই উত্তরটির উপরে একটি প্রতিস্থাপন () প্রতিস্থাপন ব্যবহার করে একটি প্যাচ প্রস্তাব দেয়। কেন না? কারণ এই সমাধানটি বাগ প্রবণ এবং 20 টি একইরকম প্রশ্ন হতে পারে তবে ভিন্ন চরিত্রের সাথে। এই কারণেই আমি বলেছিলাম এটি সংক্ষিপ্ত হয়েছে।
pyb

57

%20ইউআরএলগুলিতে এবং +ফর্মগুলিতে জমা দেওয়া ডেটাতে (কন্টেন্ট টাইপ অ্যাপ্লিকেশন / x-www-form-urlencoded) একটি স্থান এনকোড করা হয় । তোমার প্রাক্তন দরকার

পেয়ারা ব্যবহার :

dependencies {
     compile 'com.google.guava:guava:23.0'
     // or, for Android:
     compile 'com.google.guava:guava:23.0-android'
}

আপনি UrlEscapers ব্যবহার করতে পারেন :

String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);

স্ট্রিং.রেপ্লেস ব্যবহার করবেন না, এটি কেবল স্থানটি এনকোড করবে। পরিবর্তে একটি লাইব্রেরি ব্যবহার করুন।


এটি অ্যান্ড্রয়েড, com.google.guava: পেয়ারা: 22.0-rc1-android এর জন্যও কাজ করে।
বায়ভোর

1
@ বেভোর আরসি 1 এর অর্থ 1 ম রিলিজ প্রার্থী, অর্থাৎ একটি সংস্করণ এখনও সাধারণ মুক্তির জন্য অনুমোদিত নয়। আপনি যদি পারেন তবে স্ন্যাপশট, আলফা, বিটা, আরসি ছাড়াই একটি সংস্করণ বেছে নিন কারণ সেগুলি বাগগুলি ধারণ করে।
pyb

1
@ ইপিবি ধন্যবাদ, তবে আমার প্রকল্পটি শেষ হয়ে গেলে আমি libs আপডেট করব। মানে, আমি চূড়ান্ত সংস্করণ ছাড়া প্রোডে যাব না। এবং এটি এখনও অনেক সপ্তাহ নেয়, তাই আমি অনুমান করি তখন একটি চূড়ান্ত সংস্করণ আছে।

1
দুর্ভাগ্যক্রমে, পেয়ারা অ্যাপাচি এর ইউআরএল কোডেকের বিপরীতে কোনও ডিকোডার সরবরাহ করে না ।
বেনি বোত্তেমা

26

এই শ্রেণীর সঞ্চালন application/x-www-form-urlencodedবরং শতাংশ এনকোডিং চেয়ে এনকোডিং টাইপ, তাই প্রতিস্থাপন সঙ্গে +একটি সঠিক আচরণ।

জাভাডোক থেকে:

একটি স্ট্রিং এনকোড করার সময়, নিম্নলিখিত বিধিগুলি প্রয়োগ হয়:

  • বর্ণমালার অক্ষর "a" "z" এর মাধ্যমে, "A" "Z" এর মাধ্যমে এবং "0" "9" এর মাধ্যমে একই থাকে।
  • বিশেষ অক্ষর "।", "-", "*" এবং "_" একই থাকে।
  • স্থান অক্ষর "" একটি প্লাস চিহ্নে রূপান্তরিত হয় "+"।
  • অন্যান্য সমস্ত অক্ষর অনিরাপদ এবং কিছু এনকোডিং স্কিম ব্যবহার করে প্রথমে এক বা একাধিক বাইটে রূপান্তরিত হয়। তারপরে প্রতিটি বাইটটি 3-অক্ষরযুক্ত স্ট্রিং "% xy" দ্বারা প্রতিনিধিত্ব করা হয়, যেখানে xy বাইটের দুই-অঙ্কের হেক্সাডেসিমাল উপস্থাপনা। ব্যবহারের জন্য প্রস্তাবিত এনকোডিং প্রকল্পটি ইউটিএফ -8 8 যাইহোক, সামঞ্জস্যতার কারণে, যদি কোনও এনকোডিং নির্দিষ্ট না করা থাকে তবে প্ল্যাটফর্মের ডিফল্ট এনকোডিং ব্যবহৃত হয়।

@ axtavt সুন্দর ব্যাখ্যা। তবে আমার এখনও কিছু প্রশ্ন আছে। মধ্যে url, স্থানটি ব্যাখ্যা করা উচিত %20। তাহলে আমাদের কি করা দরকার url.replaceAll("\\+", "%20")? এবং এটি জাভাস্ক্রিপ্ট হলে আমাদের escapeফাংশন ব্যবহার করা উচিত নয় । ব্যবহার করুন encodeURIঅথবা encodeURIComponentপরিবর্তে। আমি যা ভেবেছিলাম.
অ্যালস্টন

1
@ স্টলম্যান এটি জাভা, জাভাস্ক্রিপ্ট নয়। সম্পূর্ণ ভিন্ন ভাষা।
চার্লস উড

19

এনকোড ক্যোয়ারী প্যারামগুলি

org.apache.commons.httpclient.util.URIUtil
    URIUtil.encodeQuery(input);

অথবা আপনি যদি ইউআরআই-এর মধ্যে অক্ষরগুলি থেকে বাঁচতে চান

public static String escapeURIPathParam(String input) {
  StringBuilder resultStr = new StringBuilder();
  for (char ch : input.toCharArray()) {
   if (isUnsafe(ch)) {
    resultStr.append('%');
    resultStr.append(toHex(ch / 16));
    resultStr.append(toHex(ch % 16));
   } else{
    resultStr.append(ch);
   }
  }
  return resultStr.toString();
 }

 private static char toHex(int ch) {
  return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
 }

 private static boolean isUnsafe(char ch) {
  if (ch > 128 || ch < 0)
   return true;
  return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
 }

3
ব্যবহার করা org.apache.commons.httpclient.util.URIUtilসমস্যাটিকে সমাধান করার সবচেয়ে কার্যকর উপায় বলে মনে হচ্ছে!
স্টাফেন আম্মার

11

Hello+Worldকোনও ব্রাউজার কীভাবে কোনও অনুরোধের application/x-www-form-urlencodedজন্য ফর্ম ডেটা ( ) এনকোড করবে GETএবং এটি কোনও ইউআরআইয়ের কোয়েরি অংশের জন্য সাধারণত গৃহীত ফর্ম।

http://host/path/?message=Hello+World

আপনি যদি কোনও জাভা সার্লেটকে এই অনুরোধটি প্রেরণ করেন তবে সার্ভলেটটি সঠিকভাবে পরামিতিটির মানটি ডিকোড করবে। সাধারণত এখানে শুধুমাত্র সমস্যাগুলি হ'ল যদি এনকোডিংটি মেলে না।

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

সাধারণত ইউআরআইর অন্যান্য অংশের (উদাহরণস্বরূপ) এই এনকোডিংটি ব্যবহার করা ভুল হবে। সেক্ষেত্রে আরএফসি 3986-তে বর্ণিত হিসাবে আপনার এনকোডিং স্কিমটি ব্যবহার করা উচিত ।

http://host/Hello%20World

আরও এখানে


5

অন্য উত্তরগুলি হ'ল ম্যানুয়াল স্ট্রিং প্রতিস্থাপন, ইউআরএলএনকোডার উপস্থাপন করে যা প্রকৃতপক্ষে এইচটিএমএল ফর্ম্যাট, অ্যাপাচি-এর পরিত্যক্ত ইউআরআইটিইল , বা গুয়ারা এর ইউরেলস্কেপস ব্যবহার করে এনকোড করে । শেষটি ঠিক আছে, বাদে এটি কোনও ডিকোডার সরবরাহ করে না।

অ্যাপাচি কমন্স ল্যাং ইউআরএল কোডেক সরবরাহ করে যা ইউআরএল ফর্ম্যাট rfc3986 অনুযায়ী এনকোড করে এবং ডিকোড করে

String encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);

আপনি যদি ইতিমধ্যে বসন্ত ব্যবহার করে থাকেন তবে আপনিও ব্যবহার করতে বেছে নিতে পারেন তার UriUtils পাশাপাশি শ্রেণী।


6
ইউআরএল কোডেক এখানে ভাল সমাধান নয় কারণ এটি ফাঁকা স্থানকে প্লাস হিসাবে এনকোড করে, তবে প্রশ্নটি ফাঁকা স্থানগুলিকে% 20 হিসাবে এনকোড করার জন্য জিজ্ঞাসা করছে।
ডেভিডভেস্টার 48

3

"+" সঠিক। আপনার যদি সত্যিই% 20 এর প্রয়োজন হয় তবে তার পরে নিজেই প্লাসগুলি প্রতিস্থাপন করুন।


5
প্রাথমিক স্ট্রিংটিতে সত্যই একটি + অক্ষর থাকলে কোনও সমস্যা হতে পারে।
অ্যালেক্সিস ডুফরনয়

17
@ ট্র্যারোথ - সত্যই নয়। +মূল পাঠ্যের একটি অক্ষর হিসাবে এনকোড হওয়ার কথা %2B
টেড হপ

+প্রসঙ্গটি না জেনে এটি সঠিক বলা কমপক্ষে, পেডেন্টিক। Downvoted। কখন + বা% 20 ব্যবহার করা হবে সে সম্পর্কে জানতে অন্যান্য উত্তরগুলি পড়ুন।
ক্লিন্ট ইস্টউড

@ ক্লিন্টইস্টউড: ইউএসএলগুলিতে স্পেসের জন্য + অক্ষরটি সঠিক নয় এমন কোনও ইউজকেস সম্পর্কে আমাকে বলতে পারেন? অন্যদিকে যখন কোনও অমীমাংসিত ইউআরএল পার্সার থাকে তখন বাদে?
ড্যানিয়েল

@ ড্যানিয়েল নিশ্চিত, "ভুল" বলছেন না তবে অনুপযুক্ত? হ্যাঁ. বিশ্লেষণ সরঞ্জামগুলি প্রায়শই একটি নির্দিষ্ট অক্ষর দ্বারা পৃথক মানগুলির সাথে ক্যোয়ারী প্যারাম ব্যবহার করে, উদাহরণস্বরূপ "+"। সেক্ষেত্রে "% 20" এর পরিবর্তে "+" ব্যবহার করা ভুল হবে। "+" কোনও ফর্মের ফাঁকা স্থানগুলি ব্যবহার করার জন্য ব্যবহৃত হয়, যখন "শতাংশ এনকোডিং" (ওরফে ইউআরএল এনকোডিং) ইউআরএলগুলিতে বেশি মনোযোগী হয়।
ক্লিন্ট ইস্টউড

3

অ্যান্ড্রয়েডে সবেমাত্র এটির সাথে লড়াই করে চলেছি, অ্যান্ড্রয়েড (android.net.Uri) এর সাথে সুনির্দিষ্ট হয়ে Uri.encode (স্ট্রিং, স্ট্রিং) দিয়ে হোঁচট খেতে পেরেছেন কারও কারও পক্ষে কার্যকর।

স্ট্যাটিক স্ট্রিং এনকোড (স্ট্রিং গুলি, স্ট্রিং অনুমতি)

https://developer.android.com/references/android/net/Uri.html#encode(java.lang.String, java.lang.String)



1

যদিও বেশ পুরানো, তবুও একটি দ্রুত প্রতিক্রিয়া:

বসন্তটি ইউরিউটিলগুলি সরবরাহ করে - এর সাহায্যে আপনি কীভাবে এনকোডিং করবেন এবং কোন অংশটি কোনও ইউআরআই থেকে সম্পর্কিত তা নির্দিষ্ট করে দিতে পারেন, যেমন

encodePathSegment
encodePort
encodeFragment
encodeUriVariables
....

আমরা ইতিমধ্যে স্প্রিং ব্যবহার করার কারণে তাদের ব্যবহার করছি, অর্থাত্ কোনও অতিরিক্ত পাঠাগার প্রয়োজন নেই!



0

আমি কি ভুল পদ্ধতি ব্যবহার করছি? আমার সঠিক পদ্ধতিটি ব্যবহার করা উচিত?

হ্যাঁ, এই পদ্ধতিটি java.net.URLEncoder.encode "(" উত্স ) অনুসারে "" "20%" তে রূপান্তর করার জন্য তৈরি করা হয়নি ।

স্থান অক্ষর "" একটি প্লাস চিহ্নে রূপান্তরিত হয় "+"।

এমনকি এটি সঠিক পদ্ধতি নয়, আপনি এটি এটিকে সংশোধন করতে পারেন: System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replaceAll("\\+", "%20"));আপনার দিনটি খুব ভাল =)।


আপনি এমন একটি পদ্ধতি ব্যবহারের পরামর্শ দিচ্ছেন যা পর্যাপ্ত নয় ( URLEncoder.encode) এবং এটি ব্যবহার করে প্যাচ করুন replaceAllযা কেবলমাত্র এই নির্দিষ্ট ক্ষেত্রে কাজ করবে। পরিবর্তে সঠিক শ্রেণী এবং পদ্ধতি ব্যবহার করুন, অন্যান্য উত্তর দেখুন।
পাইব

@pyb দেখে মনে হচ্ছে আমি কী লিখেছি তা বুঝতে পারবেন না। আমি কখনও বলিনি "আমি এটি ব্যবহার করার পরামর্শ দিই", আমি বলেছিলাম "আপনি পারবেন"। আপনি লেখার আগে পড়ুন এবং বুঝতে দয়া করে।
প্রিগ্যান্টন

এটি একটি প্রশ্নোত্তর ওয়েবসাইট, কোনও নিয়মিত বার্তা বোর্ড নয় যেখানে লোকেরা চ্যাট করে। আপনার যদি পাশের মন্তব্য থাকে তবে মন্তব্যগুলি ব্যবহার করুন। দীর্ঘ আলোচনা? চ্যাট ব্যবহার করুন। উত্তর হিসাবে আপনি অসম্মত কোড পোস্ট করবেন না। অন্যদের অবদান এবং বক্তৃতা দেওয়ার আগে দয়া করে এই সাইটের নিয়মগুলি পড়ুন এবং বুঝতে পারেন।
পাইব

1
আমি এটিকে ফিরিয়ে আনছি কারণ বেশিরভাগ অন্যান্য সমাধান একই পরামর্শ দেয়। এই পদ্ধতিটি ভুল প্রমাণ করার জন্য কোনও "নির্দিষ্ট মামলা" সরবরাহ করা হয়নি। ট্র্যাচ-ক্যাচ ব্লক বা নির্ভরতা সহ অ্যাপাচি কমন্স ব্যবহার করা কোনও পদ্ধতির জন্য খুব ঝামেলা যা কার্যকরভাবে প্রতিস্থাপনের সাথে প্যাচ করা যায়।
ইউজিন কার্তোয়েভ

-2

সমস্যাটি পরিচালনা করতে MyUrlEncode.URLencoding (স্ট্রিং url, স্ট্রিং এনক) ব্যবহার করুন

    public class MyUrlEncode {
    static BitSet dontNeedEncoding = null;
    static final int caseDiff = ('a' - 'A');
    static {
        dontNeedEncoding = new BitSet(256);
        int i;
        for (i = 'a'; i <= 'z'; i++) {
            dontNeedEncoding.set(i);
        }
        for (i = 'A'; i <= 'Z'; i++) {
            dontNeedEncoding.set(i);
        }
        for (i = '0'; i <= '9'; i++) {
            dontNeedEncoding.set(i);
        }
        dontNeedEncoding.set('-');
        dontNeedEncoding.set('_');
        dontNeedEncoding.set('.');
        dontNeedEncoding.set('*');
        dontNeedEncoding.set('&');
        dontNeedEncoding.set('=');
    }
    public static String char2Unicode(char c) {
        if(dontNeedEncoding.get(c)) {
            return String.valueOf(c);
        }
        StringBuffer resultBuffer = new StringBuffer();
        resultBuffer.append("%");
        char ch = Character.forDigit((c >> 4) & 0xF, 16);
            if (Character.isLetter(ch)) {
            ch -= caseDiff;
        }
        resultBuffer.append(ch);
            ch = Character.forDigit(c & 0xF, 16);
            if (Character.isLetter(ch)) {
            ch -= caseDiff;
        }
         resultBuffer.append(ch);
        return resultBuffer.toString();
    }
    private static String URLEncoding(String url,String enc) throws UnsupportedEncodingException {
        StringBuffer stringBuffer = new StringBuffer();
        if(!dontNeedEncoding.get('/')) {
            dontNeedEncoding.set('/');
        }
        if(!dontNeedEncoding.get(':')) {
            dontNeedEncoding.set(':');
        }
        byte [] buff = url.getBytes(enc);
        for (int i = 0; i < buff.length; i++) {
            stringBuffer.append(char2Unicode((char)buff[i]));
        }
        return stringBuffer.toString();
    }
    private static String URIEncoding(String uri , String enc) throws UnsupportedEncodingException { //对请求参数进行编码
        StringBuffer stringBuffer = new StringBuffer();
        if(dontNeedEncoding.get('/')) {
            dontNeedEncoding.clear('/');
        }
        if(dontNeedEncoding.get(':')) {
            dontNeedEncoding.clear(':');
        }
        byte [] buff = uri.getBytes(enc);
        for (int i = 0; i < buff.length; i++) {
            stringBuffer.append(char2Unicode((char)buff[i]));
        }
        return stringBuffer.toString();
    }

    public static String URLencoding(String url , String enc) throws UnsupportedEncodingException {
        int index = url.indexOf('?');
        StringBuffer result = new StringBuffer();
        if(index == -1) {
            result.append(URLEncoding(url, enc));
        }else {
            result.append(URLEncoding(url.substring(0 , index),enc));
            result.append("?");
            result.append(URIEncoding(url.substring(index+1),enc));
        }
        return result.toString();
    }

}

9
চাকাটি পুনরায় উদ্ভাবন করা, একটি কোড-বেসে সুপার ত্রুটি-প্রবণ কোড যুক্ত করা প্রায়শই একটি খারাপ সিদ্ধান্ত।
ক্লিন্ট ইস্টউড

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.