জাভাতে HTTP URL ঠিকানা এনকোডিং


366

আমার জাভা স্ট্যান্ডেলোন অ্যাপ্লিকেশনটি একটি ইউআরএল পেয়েছে (যা কোনও ফাইলের দিকে নির্দেশ করে) এবং আমাকে এটি হিট করে ডাউনলোড করতে হবে। আমি যে সমস্যার মুখোমুখি হচ্ছি তা হ'ল আমি HTTP ইউআরএল ঠিকানাটি সঠিকভাবে এনকোড করতে পারছি না ...

উদাহরণ:

URL:  http://search.barnesandnoble.com/booksearch/first book.pdf

java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");

আমাকে ফেরত দেয়:

http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf

তবে, আমি যা চাই তা হ'ল

http://search.barnesandnoble.com/booksearch/first%20book.pdf

(স্থান% 20 দ্বারা প্রতিস্থাপিত)

আমার ধারণা URLEncoder, এইচটিটিপি ইউআরএলগুলি এনকোড করার জন্য ডিজাইন করা হয়নি ... জাভাডক "HTML ফর্ম এনকোডিংয়ের জন্য ইউটিলিটি ক্লাস" বলে ... এটি করার কোনও অন্য উপায় আছে কি?



আচরণ পুরোপুরি সঠিক। ইউআরএল এনকোড হ'ল এমন কিছুকে স্ট্রিংয়ে রূপান্তরিত করা যা নিরাপদে ইউআরএল প্যারামিটার হিসাবে উত্তীর্ণ হতে পারে এবং এটি কোনও URL হিসাবে ব্যাখ্যা করা যায় না। আপনি যেখানে চান এটি কেবলমাত্র URL এর একটি ছোট অংশকে রূপান্তর করতে।
স্টিফেন হল্ট

উত্তর:


303

Java.net.URI বর্গ সাহায্য করতে পারেন; URL- এর ডকুমেন্টেশনে আপনি খুঁজে পান

দ্রষ্টব্য, ইউআরআই শ্রেণি নির্দিষ্ট পরিস্থিতিতে তার উপাদান ক্ষেত্রগুলি এড়িয়ে চলার কাজ করে। ইউআরএলগুলির এনকোডিং এবং ডিকোডিং পরিচালনা করার প্রস্তাবিত উপায় হ'ল ইউআরআই ব্যবহার করা

একাধিক যুক্তি সহ একটি নির্মাণকারীর ব্যবহার করুন, যেমন:

URI uri = new URI(
    "http", 
    "search.barnesandnoble.com", 
    "/booksearch/first book.pdf",
    null);
URL url = uri.toURL();
//or String request = uri.toString();

(ইউআরআই-এর একক-যুক্তি নির্মাণকারী অবৈধ অক্ষরগুলি এড়ায় না)


উপরের কোডের দ্বারা কেবল অবৈধ অক্ষরগুলি পালাতে পারে - এটি অ-এসসিআইআই অক্ষরগুলি এড়ায় না (ফাতেহর মন্তব্য দেখুন) পদ্ধতিটি
কেবল toASCIIStringমার্কিন-এএসসিআইআই অক্ষর দিয়ে একটি স্ট্রিং পেতে ব্যবহার করা যেতে পারে:

URI uri = new URI(
    "http", 
    "search.barnesandnoble.com", 
    "/booksearch/é",
    null);
String request = uri.toASCIIString();

কোনও প্রশ্নের মতো URL এর http://www.google.com/ig/api?weather=São Pauloজন্য, কনস্ট্রাক্টরের 5-প্যারামিটার সংস্করণটি ব্যবহার করুন:

URI uri = new URI(
        "http", 
        "www.google.com", 
        "/ig/api",
        "weather=São Paulo",
        null);
String request = uri.toASCIIString();

13
দয়া করে মনে রাখবেন, এখানে উল্লিখিত ইউআরআই ক্লাসটি "org.apache.commons.httpclient.URI" থেকে রয়েছে "আমি" java.net "নই," java.net "ইউআরআই অবৈধ অক্ষর গ্রহণ করে না, যদি না আপনি ব্যবহার করবেন
নির্মাতারা

7
@ মোহাম্মদ: আমি পরীক্ষার জন্য যে ক্লাসটি উল্লেখ করেছি এবং ব্যবহার করেছি তা হ'ল java.net.URI : এটি পুরোপুরি কাজ করেছে (জাভা ১.6) আমি পুরোপুরি যোগ্যতাসম্পন্ন শ্রেণীর নাম উল্লেখ করব যদি এটি স্ট্যান্ডার্ড জাভা না হয় এবং এর ডকুমেন্টেশনের লিঙ্ক পয়েন্ট java.net.URI। এবং, সুধাকারের মন্তব্যে, এটি কোনও "কমন্স লাইব্রেরি" অন্তর্ভুক্ত না করেই সমস্যার সমাধান করেছে!
ব্যবহারকারী 85421

1
ইউআরআই ইউরি = নতুন ইউআরআই ("http", "search.barnesandnoble.com", "/ booksearch / é", নাল); এই নমুনাটি দিয়ে সঠিকভাবে পালানো যায় না? এটি% পলায়ন সহ পালানো উচিত ছিল
fmucar

@ ফাতিহ - এটি সঠিক, ধন্যবাদ! সাধারণত এটি কোনও সমস্যা হওয়া উচিত নয়, তবে এর একটি সহজ সমাধান রয়েছে - যা আমি আগে লিখেছিলাম প্রায় একই। ২ য় সম্পাদনা দেখুন।
ব্যবহারকারী 85421

সম্পাদনার জন্য @ কার্লোস থেক্স। এখন এটি পালাতে পারে তবে পালানো সঠিক নয়। এটি পাথ প্যারামগুলির জন্য চরের HX মানতে একটি% যুক্ত করা উচিত meaning চরটি% e9- এ রূপান্তর করা উচিত
fmucar

91

দয়া করে সতর্ক হোন যে উপরের উত্তরগুলির বেশিরভাগই অসম্পূর্ণ।

URLEncoderবর্গ, সত্ত্বেও নাম, কি এখানে প্রয়োজন। দুর্ভাগ্যজনক যে সান এই শ্রেণীর নামটি এত বিরক্তিকর করে রেখেছিল। URLEncoderপ্যারামিটার হিসাবে ডেটা পাস করার জন্য বোঝানো হয়, ইউআরএল নিজেই এনকোড করার জন্য নয়।

অন্য কথায়, "http://search.barnesandnoble.com/booksearch/first book.pdf"ইউআরএল হয়। প্যারামিটারগুলি উদাহরণস্বরূপ, হবে "http://search.barnesandnoble.com/booksearch/first book.pdf?parameter1=this&param2=that"। প্যারামিটারগুলি হ'ল আপনি কী ব্যবহার URLEncoderকরবেন।

নিম্নলিখিত দুটি উদাহরণ দুজনের মধ্যে পার্থক্য তুলে ধরে।

নিম্নলিখিতটি HTTP স্ট্যান্ডার্ড অনুযায়ী ভুল পরামিতি উত্পাদন করে। নোট করুন যে এম্পারস্যান্ড (&) এবং প্লাস (+) ভুলভাবে এনকোড হয়েছে।

uri = new URI("http", null, "www.google.com", 80, 
"/help/me/book name+me/", "MY CRZY QUERY! +&+ :)", null);

// URI: http://www.google.com:80/help/me/book%20name+me/?MY%20CRZY%20QUERY!%20+&+%20:)

নিম্নলিখিতটি সঠিকভাবে এনকোডযুক্ত কোয়েরি সহ সঠিক প্যারামিটার তৈরি করবে। স্পেস, অ্যাম্পারস্যান্ড এবং আরও চিহ্নগুলি নোট করুন।

uri = new URI("http", null, "www.google.com", 80, "/help/me/book name+me/", URLEncoder.encode("MY CRZY QUERY! +&+ :)", "UTF-8"), null);

// URI: http://www.google.com:80/help/me/book%20name+me/?MY+CRZY+QUERY%2521+%252B%2526%252B+%253A%2529

2
ঠিক আছে, ডকুমেন্টেশন ডকস.অরাকল.com / javase / 1.4.2 / docs / api / java / net/… , java.lang.String, java.lang.String, int অনুযায়ী ইউআরআই কনস্ট্রাক্টর ইতিমধ্যে কোয়েরিস্ট্রিং এনকোড করেছে , java.lang.String, java.lang.String, java.lang.String)
madoke

8
@ ড্রেমন উত্তরটি সঠিক তবে কোয়েরি স্ট্রিংটিকে অস্বাভাবিক উপায়ে ব্যবহার করেছেন; আরও সাধারণ উদাহরণ হতে পারে query = URLEncoder.encode(key) + "=" + URLEncoder.encode(value)। দস্তাবেজগুলি কেবলমাত্র বলে যে "কোনও চরিত্র যা আইনী ইউআরআই চরিত্র নয়, তা উদ্ধৃত করা হয়"।
টিসি।

1
আমি এখানে ম্যাট সাথে একমত। আপনি যদি এই ইউআরএলটি টাইপ করেন: " google.com/help/me/book নাম + me /? আমার CRZY QUERY! + & + :)" ব্রাউজারে এটি স্বয়ংক্রিয়ভাবে স্পেসগুলি এনকোড করে তবে "&" কে কোয়েরি মান হিসাবে ব্যবহৃত হয় বিভাজক এবং "+" হারিয়ে গেছে।
arcot

80

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

একবার চেষ্টা করে দেখুন:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

আপনি দেখতে পাচ্ছেন যে এই বিশেষ ইউআরএলটিতে আমার সেই স্থানগুলি এনকোড করা দরকার যাতে আমি এটি একটি অনুরোধের জন্য ব্যবহার করতে পারি।

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

এই পদ্ধতির সৌন্দর্য হ'ল আপনি যে কোনও বৈধ ইউআরএল স্ট্রিং নিতে পারেন এবং এটি সম্পর্কে নিজের কোনও বিশেষ জ্ঞানের প্রয়োজন ছাড়াই এটি কাজ করতে পারেন।


3
ভাল পন্থা, তবে আমি উল্লেখ করতে চাই যে এই কোডটি ডাবল এনকোডিং প্রতিরোধ করে না , যেমন% 20%% 2520 এ এনকোড হয়েছে। স্কটের উত্তর এ থেকে ভোগেনা।
নাটস্টার

2
এটি পরিচালনা করতে পারে না #
অ্যালস্টন

অথবা আপনি যদি কেবল পথ উদ্ধৃত করতে চান: নতুন ইউআরআই (নাল, নাল, "/ স্পেস সহ পথ", নাল, নাল)। স্ট্রিং ()
ব্যবহারকারী 1050755

1
@ স্টলম্যান যদি আপনার ফাইলের নাম # থাকে তবে ইউআরএল বর্গ এটিকে "রেফ" এর মধ্যে রাখবে (ইউআরআই ক্লাসে "টুকরা" এর সমতুল্য)। URL.getRef () এমন কিছু ফেরত দেয় যা সনাক্ত করতে পারে যা পথের অংশ হিসাবে বিবেচিত হতে পারে এবং URL পাস করেছে get " "ইউআরআই ক্লাস 7 টি পরামিতি নির্মাণকারীর পরামিতি। ডিফল্টরূপে, # এর পরে স্ট্রিংটিকে একটি রেফারেন্স (বা অ্যাঙ্কর) হিসাবে বিবেচনা করা হয়।
gouessej

49

একটি সমাধান আমি বিকাশ করেছি এবং অন্য যে কোনও তুলনায় অনেক বেশি স্থিতিশীল:

public class URLParamEncoder {

    public static String encode(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
এর জন্য আপনাকে url কে টুকরো টুকরো করতে হবে requires ইউআরএলটির কোন অংশটি এনকোড করা উচিত তা কোনও কম্পিউটারের জানার উপায় নেই। আমার উপরের সম্পাদনাটি দেখুন
fmucar

4
@fmucar কোড টুকরা জন্য ধন্যবাদ! এটি লক্ষ করা উচিত যে এটি ইউটিএফ -8 নয়। ইউটিএফ -8 পেতে কেবলমাত্র এখানString utf8Input = new String(Charset.forName("UTF-8").encode(input).array()); থেকে ইনপুট প্রাক-প্রক্রিয়া করতে ( এখান থেকে নেওয়া )
লেটমাইক

1
এই সমাধানটি আসলে "http: //" অংশটিকে "HTTP% 3A% 2F% 2F" তে এনকোড করবে, যা প্রাথমিক প্রশ্ন এড়াতে চেষ্টা করেছিল।
বেনিয়ামিন পিট

2
পুরো ইউআরএল নয়, আপনি কেবল এনকোড করার দরকার যা পাস করেন pass একটি সম্পূর্ণ URL স্ট্রিং পাস করার এবং সঠিক এনকোডিংয়ের আশা করার কোনও উপায় নেই। সমস্ত ক্ষেত্রে, আপনাকে url এর লজিকাল টুকরো টুকরো করতে হবে।
fmucar

2
আমার এই উত্তরটিতে সমস্যা ছিল কারণ এটি ইউটিএফ -8 এ অনিরাপদ অক্ষরগুলি এনকোড করে না .. যদিও পিয়ার অ্যাপ্লিকেশনটির উপর নির্ভরশীল হতে পারে।
তার্নশাফ

36

আপনার যদি URL থাকে তবে আপনি url.toString () এই পদ্ধতিতে পাস করতে পারেন। ডাবল এনকোডিং এড়ানোর জন্য প্রথম ডিকোড (উদাহরণস্বরূপ,% 20-তে কোনও স্থানের ফলাফল এনকোডিং করা এবং% 25-তে একটি চিহ্ন চিহ্ন এনকোডিং করা, সুতরাং ডাবল এনকোডিং একটি স্থানকে% 2520 এ পরিণত করবে)। তারপরে, ইউআরআই এর সমস্ত অংশ যুক্ত করে উপরে বর্ণিত ইউআরআই ব্যবহার করুন (যাতে আপনি ক্যোয়ারীর প্যারামিটারগুলি না ফেলে)।

public URL convertToURLEscapingIllegalCharacters(String string){
    try {
        String decodedURL = URLDecoder.decode(string, "UTF-8");
        URL url = new URL(decodedURL);
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); 
        return uri.toURL(); 
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}

1
আপনি যখন " google.co.in/search?q=123% ! 123" হিসাবে স্ট্রিংটি পাস করেন তখন ইউআরএলডিকোডার.ডেকোড (স্ট্রিং, "ইউটিএফ -8") একটি অবৈধ অরগিউমেন্টএক্সেপশন ব্যর্থ হয় । এটি একটি বৈধ ইউআরএল। আমি অনুমান করি যখন এনকোডিং চরিত্রের পরিবর্তে% হিসাবে ডেটা হিসাবে ব্যবহৃত হয় তখন এই API টি কার্যকর হয় না।
মিডিয়ামওনে

26

হ্যাঁ ইউআরএল এনকোডিং সেই স্ট্রিংটিকে এনকোড করতে চলেছে যাতে এটি কোনও url এ চূড়ান্ত গন্তব্যে যেতে পারে। উদাহরণস্বরূপ আপনি http://stackoverflow.com?url=http://yyy.com থাকতে পারেন নি । পরামিতিটি urlEncoding প্যারামিটার মানটি স্থির করবে।

সুতরাং আপনার জন্য আমার দুটি পছন্দ আছে:

  1. আপনি কি ডোমেন থেকে পৃথক পথ অ্যাক্সেস আছে? যদি তা হয় তবে আপনি কেবল urlEncode পথটি সক্ষম করতে পারেন। তবে, যদি এটি না হয় তবে বিকল্প 2 আপনার জন্য হতে পারে।

  2. Commons-httpclient-3.1 পান। এটির একটি শ্রেণি ইউআরআইইটি রয়েছে:

    System.out.println (URIUtil.encodePath (" http://example.com/x y", "আইএসও -8859-1 "));

এটি আপনি যা সন্ধান করছেন ঠিক তার ফলস্বরূপ আসবে, কারণ এটি কেবল ইউআরআইয়ের পথ অংশকেই এনকোড করবে।

এফওয়াইআই, রানটাইম এ কাজ করার জন্য আপনার কমন্স-কোডেক এবং কমন্স-লগিং দরকার।


সিডনোট অ্যাপাচি কমন্সগুলি 4.x শাখায় স্পষ্টতই ইউআরআইটিইল বজায় রাখা বন্ধ করে দিয়েছে, পরিবর্তে আপনি জেডিকে এর ইউআরআই ক্লাস ব্যবহার করার পরামর্শ দিচ্ছেন। কেবলমাত্র আপনাকে নিজেরাই স্ট্রিংটি ভেঙে ফেলতে হবে।
নিকলি

2) ঠিক এখানে পরামর্শ দেওয়া হয় stackoverflow.com/questions/5330104/... আমিও ব্যবহৃত URIUtilসমাধান
করতে ক্রা

11

নিতপিকিং: সংজ্ঞা অনুসারে একটি শ্বেতক্ষেত্রের অক্ষরযুক্ত একটি স্ট্রিং কোনও ইউআরআই নয়। সুতরাং আপনি যা সন্ধান করছেন তা হ'ল আরএফসি 3986 এর ধারা 2.1-এ সংজ্ঞায়িত ইউআরআই পলায়নের কার্যকর করে ।


আমাদের উত্তরের "কীভাবে" দরকার, "কী" নয়।
shinzou

11

দুর্ভাগ্যক্রমে, org.apache.commons.httpclient.util.URIUtilঅবহেলা করা হয়েছে, এবং replacement org.apache.commons.codec.net.URLCodecফর্ম পোস্টগুলির জন্য কোডিং উপযুক্ত, বাস্তব URL- তে নয় actual সুতরাং আমাকে নিজের ফাংশনটি লিখতে হয়েছিল, যা একটি একক উপাদান (পুরো ক্যোয়ারী স্ট্রিংগুলির জন্য উপযুক্ত নয়? এর গুলি এবং এর গুলি)

public static String encodeURLComponent(final String s)
{
  if (s == null)
  {
    return "";
  }

  final StringBuilder sb = new StringBuilder();

  try
  {
    for (int i = 0; i < s.length(); i++)
    {
      final char c = s.charAt(i);

      if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) ||
          ((c >= '0') && (c <= '9')) ||
          (c == '-') ||  (c == '.')  || (c == '_') || (c == '~'))
      {
        sb.append(c);
      }
      else
      {
        final byte[] bytes = ("" + c).getBytes("UTF-8");

        for (byte b : bytes)
        {
          sb.append('%');

          int upper = (((int) b) >> 4) & 0xf;
          sb.append(Integer.toHexString(upper).toUpperCase(Locale.US));

          int lower = ((int) b) & 0xf;
          sb.append(Integer.toHexString(lower).toUpperCase(Locale.US));
        }
      }
    }

    return sb.toString();
  }
  catch (UnsupportedEncodingException uee)
  {
    throw new RuntimeException("UTF-8 unsupported!?", uee);
  }
}

আসুন, এমন একটি গ্রন্থাগার থাকতে হবে যা এটি করে।
shinzou

9

দুর্ভাগ্যক্রমে আবিষ্কার করা হিসাবে ইউআরএলএনকোডিং HTTP ইউআরএলগুলি ঠিক ঠিক এনকোড করতে পারে। " Http://search.barnesandnoble.com/booksearch/first book.pdf" আপনি যে স্ট্রিংটি দিয়ে গেছেন সেটি সঠিকভাবে এবং সম্পূর্ণরূপে URL- এনকোডযুক্ত ফর্মের মধ্যে এনকোড। আপনি কোনও ইউআরএল-এর পরামিতি হিসাবে ফিরে পেয়েছেন গাবলডইগুকের পুরো দীর্ঘ স্ট্রিংটি পার করে দিতে পারেন এবং আপনি যে স্ট্রিংটি পাশ করেছেন ঠিক সেদিকেই এটি ডিকোড করা যেতে পারে।

দেখে মনে হচ্ছে আপনি প্যারামিটার হিসাবে পুরো ইউআরএল পাস করার চেয়ে কিছুটা আলাদা করতে চান। আমি যা সংগ্রহ করি তা থেকে আপনি একটি অনুসন্ধান URL তৈরি করার চেষ্টা করছেন যা দেখতে " http://search.barnesandnoble.com/booksearch/w যাইহোকহু ইউজারপ্যাসেস ইন " এর মতো দেখাচ্ছে । আপনার কেবলমাত্র এনকোড করার দরকার হ'ল "যাইহোক theUserPassesIn" বিট, তাই সম্ভবত আপনাকে যা করতে হবে তা হ'ল এই জাতীয় কিছু:

String url = "http://search.barnesandnoble.com/booksearch/" + 
       URLEncoder.encode(userInput,"UTF-8");

এটি আপনার জন্য আরও বৈধ কিছু তৈরি করা উচিত।


17
এটি ব্যবহারকারীর ইনপুটগুলিতে ফাঁকা স্থানগুলি "+" দিয়ে প্রতিস্থাপন করবে। পোস্টারগুলিতে তাদের "% 20" দিয়ে প্রতিস্থাপন করা দরকার।
ভোকো

@ ভোকারো: এটি একটি খুব ভাল বিষয়। ইউআরএলএনকোডারটি আর্গুমেন্টের মতো ক্যোয়ারি প্যারামিটারগুলির মতো পালিয়ে যায়, বাকি URL এর মতো নয় like
ব্র্যান্ডন ইয়ারব্রু

9

যদি কেউ তাদের প্রকল্পের উপর নির্ভরতা যুক্ত করতে না চান তবে এই ফাংশনগুলি সহায়ক হতে পারে।

আমরা আমাদের URL এর 'পথ' অংশটি এখানে প্রবেশ করি। আপনি সম্ভবত প্যারামিটার হিসাবে পুরো ইউআরএলটি পাস করতে চান না (ক্যোয়ারী স্ট্রিংগুলির জন্য বিভিন্ন পলায়ন ইত্যাদির দরকার আছে)।

/**
 * Percent-encodes a string so it's suitable for use in a URL Path (not a query string / form encode, which uses + for spaces, etc)
 */
public static String percentEncode(String encodeMe) {
    if (encodeMe == null) {
        return "";
    }
    String encoded = encodeMe.replace("%", "%25");
    encoded = encoded.replace(" ", "%20");
    encoded = encoded.replace("!", "%21");
    encoded = encoded.replace("#", "%23");
    encoded = encoded.replace("$", "%24");
    encoded = encoded.replace("&", "%26");
    encoded = encoded.replace("'", "%27");
    encoded = encoded.replace("(", "%28");
    encoded = encoded.replace(")", "%29");
    encoded = encoded.replace("*", "%2A");
    encoded = encoded.replace("+", "%2B");
    encoded = encoded.replace(",", "%2C");
    encoded = encoded.replace("/", "%2F");
    encoded = encoded.replace(":", "%3A");
    encoded = encoded.replace(";", "%3B");
    encoded = encoded.replace("=", "%3D");
    encoded = encoded.replace("?", "%3F");
    encoded = encoded.replace("@", "%40");
    encoded = encoded.replace("[", "%5B");
    encoded = encoded.replace("]", "%5D");
    return encoded;
}

/**
 * Percent-decodes a string, such as used in a URL Path (not a query string / form encode, which uses + for spaces, etc)
 */
public static String percentDecode(String encodeMe) {
    if (encodeMe == null) {
        return "";
    }
    String decoded = encodeMe.replace("%21", "!");
    decoded = decoded.replace("%20", " ");
    decoded = decoded.replace("%23", "#");
    decoded = decoded.replace("%24", "$");
    decoded = decoded.replace("%26", "&");
    decoded = decoded.replace("%27", "'");
    decoded = decoded.replace("%28", "(");
    decoded = decoded.replace("%29", ")");
    decoded = decoded.replace("%2A", "*");
    decoded = decoded.replace("%2B", "+");
    decoded = decoded.replace("%2C", ",");
    decoded = decoded.replace("%2F", "/");
    decoded = decoded.replace("%3A", ":");
    decoded = decoded.replace("%3B", ";");
    decoded = decoded.replace("%3D", "=");
    decoded = decoded.replace("%3F", "?");
    decoded = decoded.replace("%40", "@");
    decoded = decoded.replace("%5B", "[");
    decoded = decoded.replace("%5D", "]");
    decoded = decoded.replace("%25", "%");
    return decoded;
}

এবং পরীক্ষা:

@Test
public void testPercentEncode_Decode() {
    assertEquals("", percentDecode(percentEncode(null)));
    assertEquals("", percentDecode(percentEncode("")));

    assertEquals("!", percentDecode(percentEncode("!")));
    assertEquals("#", percentDecode(percentEncode("#")));
    assertEquals("$", percentDecode(percentEncode("$")));
    assertEquals("@", percentDecode(percentEncode("@")));
    assertEquals("&", percentDecode(percentEncode("&")));
    assertEquals("'", percentDecode(percentEncode("'")));
    assertEquals("(", percentDecode(percentEncode("(")));
    assertEquals(")", percentDecode(percentEncode(")")));
    assertEquals("*", percentDecode(percentEncode("*")));
    assertEquals("+", percentDecode(percentEncode("+")));
    assertEquals(",", percentDecode(percentEncode(",")));
    assertEquals("/", percentDecode(percentEncode("/")));
    assertEquals(":", percentDecode(percentEncode(":")));
    assertEquals(";", percentDecode(percentEncode(";")));

    assertEquals("=", percentDecode(percentEncode("=")));
    assertEquals("?", percentDecode(percentEncode("?")));
    assertEquals("@", percentDecode(percentEncode("@")));
    assertEquals("[", percentDecode(percentEncode("[")));
    assertEquals("]", percentDecode(percentEncode("]")));
    assertEquals(" ", percentDecode(percentEncode(" ")));

    // Get a little complex
    assertEquals("[]]", percentDecode(percentEncode("[]]")));
    assertEquals("a=d%*", percentDecode(percentEncode("a=d%*")));
    assertEquals(")  (", percentDecode(percentEncode(")  (")));
    assertEquals("%21%20%2A%20%27%20%28%20%25%20%29%20%3B%20%3A%20%40%20%26%20%3D%20%2B%20%24%20%2C%20%2F%20%3F%20%23%20%5B%20%5D%20%25",
                    percentEncode("! * ' ( % ) ; : @ & = + $ , / ? # [ ] %"));
    assertEquals("! * ' ( % ) ; : @ & = + $ , / ? # [ ] %", percentDecode(
                    "%21%20%2A%20%27%20%28%20%25%20%29%20%3B%20%3A%20%40%20%26%20%3D%20%2B%20%24%20%2C%20%2F%20%3F%20%23%20%5B%20%5D%20%25"));

    assertEquals("%23456", percentDecode(percentEncode("%23456")));

}

এর জন্য ধন্যবাদ, তবে একটি স্থান এনকোড করতে আমার কী করা দরকার -> আপনার উদাহরণ অনুসারে% 20 ব্যবহার করুন?
N00b PR0grammer

% 20 হিসাবে স্পেসগুলির অ্যাকাউন্টে আপডেট হয়েছে
কুগা

7

আপনি যদি আপনার ইউআরএলে একটি এনকোডযুক্ত "/" (% 2F) পেয়ে থাকেন তবে এখনও সমস্যা আছে।

আরএফসি 3986 - বিভাগ ২.২ বলছে: "যদি কোনও ইউআরআই উপাদানগুলির জন্য ডেটা একটি সীমিত চরিত্রের সীমানা হিসাবে উদ্দেশ্য নিয়ে বিরোধিত করে, তবে ইউআরআই গঠনের আগে বিবাদী ডেটা অবশ্যই শতাংশ-এনকোড হওয়া উচিত" " (আরএফসি 3986 - বিভাগ 2.2)

তবে টমকেটের সাথে একটি সমস্যা রয়েছে:

http://tomcat.apache.org/security-6.html - অ্যাপাচি টমক্যাট 6.0.10 এ স্থির করা হয়েছে

গুরুত্বপূর্ণ: ডিরেক্টরি traversal CVE-2007-0450

টমক্যাট '\', '% 2F' এবং '% 5 সি' অনুমতি দেয় [...]।

নিম্নলিখিত জাভা সিস্টেমের বৈশিষ্ট্যগুলি ইউআরএলগুলিতে পাথ ডেলিমিটারগুলির পরিচালনা করার অতিরিক্ত নিয়ন্ত্রণ প্রদানের জন্য টমক্যাটটিতে যুক্ত করা হয়েছে (উভয় বিকল্পের ক্ষেত্রে মিথ্যা হিসাবে ডিফল্ট):

  • org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: সত্য | মিথ্যা
  • org.apache.catalina.connector. CoyoteAdapter.ALLOW_BACKSLASH: সত্য | মিথ্যা

প্রক্সি সার্ভারে থাকাকালীন সমস্ত ইউআরএলগুলি টমক্যাট দ্বারা পরিচালিত হয়েছে তার গ্যারান্টি দেওয়ার অসম্ভবতার কারণে টমক্যাট সর্বদা সুরক্ষিত হওয়া উচিত যেন কোনও প্রক্সির প্রসঙ্গ অ্যাক্সেসকে সীমাবদ্ধ করে না।

প্রভাব: 6.0.0-6.0.9

সুতরাং যদি আপনি% 2F অক্ষরের সাথে একটি ইউআরএল পেয়ে থাকেন, টমক্যাট ফিরে আসে: "400 অবৈধ ইউআরআই: নং স্ল্যাশ"

টমক্যাট স্টার্টআপ স্ক্রিপ্টে আপনি বাগফিক্সটি পরিবর্তন করতে পারেন:

set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%   -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true 

7

আমি আমার নিজস্ব পদ্ধতি লেখার জন্য পূর্ববর্তী উত্তরগুলি পড়েছি কারণ পূর্ববর্তী উত্তরগুলির সমাধানটি ব্যবহার করে আমার কিছু ঠিকঠাকভাবে কাজ করতে পারিনি, এটি আমার পক্ষে ভাল লাগছে তবে আপনি যদি এটির সাথে কাজ করে না এমন URL খুঁজে পেতে পারেন তবে দয়া করে আমাকে জানান।

public static URL convertToURLEscapingIllegalCharacters(String toEscape) throws MalformedURLException, URISyntaxException {
            URL url = new URL(toEscape);
            URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
            //if a % is included in the toEscape string, it will be re-encoded to %25 and we don't want re-encoding, just encoding
            return new URL(uri.toString().replace("%25", "%"));
}

4

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

বিশেষ করে সাদা স্থান অক্ষরের এনকোডিংয়ের জন্য। URL টির জন্য এটি% 20 হিসাবে এনকোড করা দরকার, যেখানে ক্যোয়ারী অংশটি% 20 এবং "+" চিহ্নটিকেও মঞ্জুরি দেয়। ওয়েব ব্রাউজার ব্যবহার করে আমাদের ওয়েব সার্ভারের বিপরীতে এটিকে পরীক্ষা করা সবচেয়ে ভাল ধারণা।

উভয় ক্ষেত্রেই, আমি সবসময় কম্পোনেন্টের মাধ্যমে কম্পোনেন্টটি এনকোড করব , পুরো স্ট্রিংটি কখনও নয়। প্রকৃতপক্ষে URLEncoder ক্যোরি অংশের জন্য এটি অনুমতি দেয় allows পথ অংশের জন্য আপনি ক্লাস ইউআরআই ব্যবহার করতে পারেন, যদিও এই ক্ষেত্রে এটি পুরো স্ট্রিংয়ের জন্য জিজ্ঞাসা করে, একটি উপাদান নয়।

যাইহোক, আমি বিশ্বাস করি যে এই সমস্যাগুলি এড়ানোর সর্বোত্তম উপায় হ'ল ব্যক্তিগত অ-বিবাদী নকশা ব্যবহার করা। কিভাবে? উদাহরণস্বরূপ, আমি কখনই ডিরেক্টরি বা প্যারামিটারগুলি এজেড, এজেড, 0-9 এবং _ এর চেয়ে অন্যান্য অক্ষর ব্যবহার করে নাম রাখব না। এইভাবে, কেবলমাত্র প্রতিটি প্যারামিটারের মানটি এনকোড করা দরকার, কারণ এটি কোনও ব্যবহারকারীর ইনপুট থেকে আসতে পারে এবং ব্যবহৃত অক্ষরগুলি অজানা।


2
প্রশ্নের URL টি ব্যবহার করে স্যাম্পল কোডটি আপনার উত্তরে রাখা ভাল জিনিস হবে
মার্টিন সেরানো


3

আপনি ব্যবহার করতে পারেন GUAVAএবং এস্কেস্টার পাথ: UrlEscapers.urlFragmentEscaper().escape(relativePath)


2

কার্লোস হুবার্গারের জবাব ছাড়াও: যদি ডিফল্ট (80) এর চেয়ে আলাদা হয় তবে 7 টি প্যারাম কনস্ট্রাক্টর ব্যবহার করা উচিত:

URI uri = new URI(
        "http",
        null, // this is for userInfo
        "www.google.com",
        8080, // port number as int
        "/ig/api",
        "weather=São Paulo",
        null);
String request = uri.toASCIIString();

2

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

/***
 * Replaces any character not specifically unreserved to an equivalent 
 * percent sequence.
 * @param s
 * @return
 */
public static String encodeURIcomponent(String s)
{
    StringBuilder o = new StringBuilder();
    for (char ch : s.toCharArray()) {
        if (isSafe(ch)) {
            o.append(ch);
        }
        else {
            o.append('%');
            o.append(toHex(ch / 16));
            o.append(toHex(ch % 16));
        }
    }
    return o.toString();
}

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

// https://tools.ietf.org/html/rfc3986#section-2.3
public static final HashSet<Character> UnreservedChars = new HashSet<Character>(Arrays.asList(
        'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
        '0','1','2','3','4','5','6','7','8','9',
        '-','_','.','~'));
public static boolean isSafe(char ch)
{
    return UnreservedChars.contains(ch);
}

1

নিম্নলিখিত মানক জাভা সমাধান ব্যবহার করুন ( ওয়েব প্লাটফর্ম টেস্ট দ্বারা সরবরাহিত টেস্টকেসগুলির প্রায় 100 টি পাস করে ):

0. URL টি ইতিমধ্যে এনকোড করা আছে কিনা তা পরীক্ষা করুন

1. স্ট্রাকচারাল অংশগুলিতে ইউআরএল বিভক্ত করুন। java.net.URL এটির জন্য ব্যবহার করুন ।

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

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

৪.java.net.URI.toASCIIString() শতাংশ-এনকোডে ব্যবহার করুন , এনএফসি এনকোডেড ইউনিকোড - (এনএফকেসি আরও ভাল হবে)।

এখানে আরও সন্ধান করুন: https://stackoverflow.com/a/49796882/1485527


0

আমি এইচটিটিপি ইউআরএলগুলি তৈরিতে সহায়তা করতে একটি নতুন প্রকল্প তৈরি করেছি। লাইব্রেরিটি স্বয়ংক্রিয়ভাবে ইউআরএল পথের অংশগুলিকে এবং ক্যোয়ারের প্যারামিটারগুলিকে প্রবেশ করবে।

আপনি উত্সটি দেখতে এবং একটি বাইনারি https://github.com/Widen/urlbuilder এ ডাউনলোড করতে পারেন

এই প্রশ্নের উদাহরণ URL:

new UrlBuilder("search.barnesandnoble.com", "booksearch/first book.pdf").toString()

উত্পাদন করে

http://search.barnesandnoble.com/booksearch/first%20book.pdf


0

আমারও একই সমস্যা ছিল। আনসেস করে এটি সমাধান করুন:

android.net.Uri.encode(urlString, ":/");

এটি স্ট্রিংটিকে এনকোড করে তবে ":" এবং "/" এড়িয়ে যায়।


0

আমি এটি ব্যবহার করি

org.apache.commons.text.StringEscapeUtils.escapeHtml4("my text % & < >");

এই dependecy যোগ করুন

 <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.8</version>
    </dependency>

-2

আমি একটি লাইব্রেরি বিকাশ করি যা এই উদ্দেশ্যে কাজ করে: গালিমাটিয়াস । এটি ওয়েব ব্রাউজারগুলির মতোই ইউআরএলকে পার্স করে। এটি হ'ল, যদি কোনও ব্রাউজারে কোনও URL কাজ করে তবে এটি গালিমাটিয়াস দ্বারা সঠিকভাবে পার্স করা হবে

এক্ষেত্রে:

// Parse
io.mola.galimatias.URL.parse(
    "http://search.barnesandnoble.com/booksearch/first book.pdf"
).toString()

আপনাকে দিতে হবে: http://search.barnesandnoble.com/booksearch/first%20book.pdf। অবশ্যই এটি সবচেয়ে সহজ কেস, তবে এটি কিছু ছাড়িয়েও কাজ করবে beyondjava.net.URI

আপনি এটি এখানে দেখতে পারেন: https://github.com/smola/galimatias


-3

আপনি এই মত একটি ফাংশন ব্যবহার করতে পারেন। এটি আপনার প্রয়োজন অনুসারে সম্পূর্ণ করুন এবং সংশোধন করুন:

/**
     * Encode URL (except :, /, ?, &, =, ... characters)
     * @param url to encode
     * @param encodingCharset url encoding charset
     * @return encoded URL
     * @throws UnsupportedEncodingException
     */
    public static String encodeUrl (String url, String encodingCharset) throws UnsupportedEncodingException{
            return new URLCodec().encode(url, encodingCharset).replace("%3A", ":").replace("%2F", "/").replace("%3F", "?").replace("%3D", "=").replace("%26", "&");
    }

ব্যবহারের উদাহরণ:

String urlToEncode = ""http://www.growup.com/folder/intérieur-à_vendre?o=4";
Utils.encodeUrl (urlToEncode , "UTF-8")

ফলাফলটি: http://www.growup.com/folder/int%C3%A9rieur-%C3%A0_vendre?o=4


1
এই উত্তরটি URLCodec ব্যতীত অসম্পূর্ণ।
লার্নের মারকুইস

.replace () শৃঙ্খলার জন্য upvote, এটি আদর্শ নয় তবে এটি বেসিক অ্যাডহক ব্যবহারের ক্ষেত্রে যথেষ্ট
svarog

-5

স্ট্রিং url = "" http://search.barnesandnoble.com/booksearch/ ;

এটি আমার ধারনা স্থির থাকবে এবং কেবল ফাইলের নাম পরিবর্তন করে তাই ফাইলের নাম পান

স্ট্রিং ফাইলের নাম; // ফাইলের নাম পান

স্ট্রিং urlEnc = url + fileName.replace ("", "% 20");


2
অন্য সব অবৈধ চরিত্রের কী হবে?
মারকুইস

-7

কেমন:

পাবলিক স্ট্রিং UrlEncode (স্ট্রিং ইন_) {

String retVal = "";

try {
    retVal = URLEncoder.encode(in_, "UTF8");
} catch (UnsupportedEncodingException ex) {
    Log.get().exception(Log.Level.Error, "urlEncode ", ex);
}

return retVal;

}


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