জাভা স্ক্রিপ্টের এনকোডিউআরআইকিউম্পোনেন্টের সমান জাভা যা অভিন্ন আউটপুট উত্পাদন করে?


92

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

আমার নির্যাতনের পরীক্ষার স্ট্রিংটি হ'ল: "এ" বি ± "

আমি যদি ফায়ারবগে নিম্নলিখিত জাভাস্ক্রিপ্ট বিবৃতিটি প্রবেশ করি:

encodeURIComponent('"A" B ± "');

-তখন আমি পাই:

"%22A%22%20B%20%C2%B1%20%22"

এখানে আমার ছোট পরীক্ষা জাভা প্রোগ্রাম:

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class EncodingTest
{
  public static void main(String[] args) throws UnsupportedEncodingException
  {
    String s = "\"A\" B ± \"";
    System.out.println("URLEncoder.encode returns "
      + URLEncoder.encode(s, "UTF-8"));

    System.out.println("getBytes returns "
      + new String(s.getBytes("UTF-8"), "ISO-8859-1"));
  }
}

এই প্রোগ্রামের ফলাফল:

URLEncoder.encode% 22A% 22 + B +% C2% B1 +% 22 প্রদান করে
getBytes "A" B ± "ফেরত দেয়

বন্ধ, তবে সিগার নেই! জাভা ব্যবহার করে কোনও ইউটিএফ -8 স্ট্রিংটি এনকোড করার সর্বোত্তম উপায় কী তা যাতে এটি জাভাস্ক্রিপ্টের মতো একই আউটপুট তৈরি করে encodeURIComponent?

সম্পাদনা: আমি খুব শীঘ্রই জাভা 5 এ সরিয়ে জাভা ব্যবহার করছি।

উত্তর:


63

বাস্তবায়নের পার্থক্যগুলি দেখে আমি দেখতে পাচ্ছি:

এমডিসি চালুencodeURIComponent() :

  • আক্ষরিক অক্ষর (রেজেক্স উপস্থাপনা): [-a-zA-Z0-9._*~'()!]

জাভা 1.5.0 ডকুমেন্টেশন এতেURLEncoder :

  • আক্ষরিক অক্ষর (রেজেক্স উপস্থাপনা): [-a-zA-Z0-9._*]
  • স্থান অক্ষর " "একটি প্লাস চিহ্নে রূপান্তরিত হয় "+"

সুতরাং মূলত, পছন্দসই ফলাফল পেতে ব্যবহার করুন URLEncoder.encode(s, "UTF-8")এবং তারপরে কিছু পোস্ট-প্রসেসিং করুন:

  • এর "+"সাথে সমস্ত ঘটনা প্রতিস্থাপন করুন"%20"
  • আক্ষরিক পাল্টা অংশগুলিতে যে কোনওটিকে "%xx"উপস্থাপনের সমস্ত উপস্থিতি প্রতিস্থাপন করুন[~'()!]

আমি আশা করি আপনি কিছু সরল ভাষায় "[~ '()!] এর কোনওটির প্রতিনিধিত্ব করে"% xx "এর সমস্ত উপস্থিতি প্রতিস্থাপন করেছেন"। :( আমার ক্ষুদ্র মাথা এটি বুঝতে সক্ষম হয় না .......
শৈলেন্দ্র সিং রাজাওয়াত

4
@Shailendra [~'()!]উপায়ে "~"বা "'"বা "("বা ")"বা "!"। :) আমি অবশ্য রেজিেক্স বুনিয়াদি শিখার পরামর্শ দিই। (আমি
এটিতেও

4
এর সমস্ত সংঘটন প্রতিস্থাপন "+"সঙ্গে "%20"যেমন, সম্ভাব্য ধ্বংসাত্মক "+"কোনো URI পাথ একটি আইনি চরিত্র (যদিও না কোয়েরি স্ট্রিং) হয়। উদাহরণস্বরূপ, "a + b c" এ হিসাবে এনকোড করা উচিত "a+b%20c"; এই সমাধান এটি রূপান্তর করতে হবে "a%20b%20c"। পরিবর্তে, ব্যবহার করুন new URI(null, null, value, null).getRawPath()
ক্রিস নিচি

@ ক্রিসনিচি এটি প্রশ্নের মূল বিষয় ছিল না। প্রশ্নটি ছিল "জাভা স্ক্রিপ্টের এনকোডিয়ুরিকম্পোনেন্টের অনুরূপ আউটপুট উত্পাদন করে? , "জেনেরিক জাভা এনকোড-ইউআরআই-উপাদান ফাংশন নয়?"
তোমালাক

118

এই ক্লাসটি আমি শেষ পর্যন্ত নিয়ে এসেছি:

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * Utility class for JavaScript compatible UTF-8 encoding and decoding.
 * 
 * @see http://stackoverflow.com/questions/607176/java-equivalent-to-javascripts-encodeuricomponent-that-produces-identical-output
 * @author John Topley 
 */
public class EncodingUtil
{
  /**
   * Decodes the passed UTF-8 String using an algorithm that's compatible with
   * JavaScript's <code>decodeURIComponent</code> function. Returns
   * <code>null</code> if the String is <code>null</code>.
   *
   * @param s The UTF-8 encoded String to be decoded
   * @return the decoded String
   */
  public static String decodeURIComponent(String s)
  {
    if (s == null)
    {
      return null;
    }

    String result = null;

    try
    {
      result = URLDecoder.decode(s, "UTF-8");
    }

    // This exception should never occur.
    catch (UnsupportedEncodingException e)
    {
      result = s;  
    }

    return result;
  }

  /**
   * Encodes the passed String as UTF-8 using an algorithm that's compatible
   * with JavaScript's <code>encodeURIComponent</code> function. Returns
   * <code>null</code> if the String is <code>null</code>.
   * 
   * @param s The String to be encoded
   * @return the encoded String
   */
  public static String encodeURIComponent(String s)
  {
    String result = null;

    try
    {
      result = URLEncoder.encode(s, "UTF-8")
                         .replaceAll("\\+", "%20")
                         .replaceAll("\\%21", "!")
                         .replaceAll("\\%27", "'")
                         .replaceAll("\\%28", "(")
                         .replaceAll("\\%29", ")")
                         .replaceAll("\\%7E", "~");
    }

    // This exception should never occur.
    catch (UnsupportedEncodingException e)
    {
      result = s;
    }

    return result;
  }  

  /**
   * Private constructor to prevent this class from being instantiated.
   */
  private EncodingUtil()
  {
    super();
  }
}

4
একটি টিপ যোগ করা হচ্ছে। অ্যান্ড্রয়েড ৪.৪-তে আমি দেখতে পেয়েছি যে আমাদের এন্ড্রয়েড ইনপুটটিতে %0Aএকটি রিটার্ন কী যার অর্থ এটিও প্রতিস্থাপন করতে হবে, বা এটি জেএসটি ক্র্যাশ করবে।
অলং

আপনি কি এখানে সবকিছু কভার করেন: developer.mozilla.org/en-US/docs/Web/JavaScript/References/…
কামাচি

4
@ অলং প্রতিস্থাপনের অর্থ কী "%0A"? কোন চরিত্রটি প্রতিস্থাপন হবে? এটা কি খালি স্ট্রিং ""?
হেলেনডাব্লুডি

15

জাভা স্ক্রিপ্ট ইঞ্জিন যা জাভা 6 সহ প্রেরণ করা হয়েছে তা ব্যবহার করে:


import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Wow
{
    public static void main(String[] args) throws Exception
    {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        engine.eval("print(encodeURIComponent('\"A\" B ± \"'))");
    }
}

আউটপুট:% 22A% 22% 20B% 20% সি 2% বি 1% 20% 22

কেসটি আলাদা তবে এটি আপনি যা চান তার কাছাকাছি।


আহ, দুঃখিত ... আমি প্রশ্নে উল্লেখ করা উচিত ছিল যে আমি খুব শীঘ্রই জাভা 1.4 এ জাভা 5 এ চলেছি!
জন টপলি

4
জাভাস্ক্রিপ্ট যদি একমাত্র সমাধান হয় তবে আপনি রাইনো চেষ্টা করতে পারেন তবে এটি এই ছোট সমস্যাটির জন্য খুব বেশি।
রবি ওয়ালাউ

4
এমনকি তিনি জাভা using ব্যবহার করছেন, আমি মনে করি এই সমাধানটি শীর্ষে রয়েছে। আমি মনে করি না যে তিনি সরাসরি জাভাস্ক্রিপ্ট পদ্ধতিটি শুরু করার উপায় খুঁজছেন, কেবল এটি অনুকরণ করার একটি উপায়।
আউটলা প্রোগ্রামার

4
হতে পারে. আমি মনে করি সবচেয়ে সহজ সমাধান হ'ল যদি আপনি নিজের জন্য কৌশলটি আবিষ্কার করে এমন কিছু খুঁজে না পান তবে আপনার নিজের পলায়ন ফাংশনটি লিখতে হবে। কেবল স্ট্রিংএস্কেপটিস ক্লাস (জাকার্তা কমন্স ল্যাং) থেকে কিছু পদ্ধতি অনুলিপি করুন এবং এটি আপনার প্রয়োজনীয়তার সাথে সংশোধন করুন।
রবি ওয়ালাউ

4
এটি আসলে কাজ করে, এবং আপনি যদি পারফরম্যান্স নিয়ে চিন্তিত না হন ... আমি মনে করি এটি ভাল।
2rs2ts

8

আমি java.net.URI#getRawPath()যেমন ব্যবহার করি

String s = "a+b c.html";
String fixed = new URI(null, null, s, null).getRawPath();

এর মান fixedহবে a+b%20c.htmlযা আপনি চান তা।

আউটপুট পরবর্তী প্রক্রিয়াকরণের URLEncoder.encode()কোনো pluses যে ধ্বংস করা হবে অনুমিত কোনো URI করা। উদাহরণ স্বরূপ

URLEncoder.encode("a+b c.html").replaceAll("\\+", "%20");

আপনাকে দেবে a%20b%20c.html, যা হিসাবে ব্যাখ্যা করা হবে a b c.html


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

এর মতো স্ট্রিংয়ের জন্য কাজ করে না http://a+b c.html
:,

5

আমি এনকোডিউরিক কম্পোনেন্টটির নিজস্ব সংস্করণ নিয়ে এসেছি, কারণ পোস্ট সমাধানটিতে একটি সমস্যা আছে, যদি স্ট্রিংটিতে একটি + উপস্থিত থাকে, যা এনকোড করা উচিত ছিল, এটি একটি স্পেসে রূপান্তরিত হবে।

সুতরাং এখানে আমার ক্লাস:

import java.io.UnsupportedEncodingException;
import java.util.BitSet;

public final class EscapeUtils
{
    /** used for the encodeURIComponent function */
    private static final BitSet dontNeedEncoding;

    static
    {
        dontNeedEncoding = new BitSet(256);

        // a-z
        for (int i = 97; i <= 122; ++i)
        {
            dontNeedEncoding.set(i);
        }
        // A-Z
        for (int i = 65; i <= 90; ++i)
        {
            dontNeedEncoding.set(i);
        }
        // 0-9
        for (int i = 48; i <= 57; ++i)
        {
            dontNeedEncoding.set(i);
        }

        // '()*
        for (int i = 39; i <= 42; ++i)
        {
            dontNeedEncoding.set(i);
        }
        dontNeedEncoding.set(33); // !
        dontNeedEncoding.set(45); // -
        dontNeedEncoding.set(46); // .
        dontNeedEncoding.set(95); // _
        dontNeedEncoding.set(126); // ~
    }

    /**
     * A Utility class should not be instantiated.
     */
    private EscapeUtils()
    {

    }

    /**
     * Escapes all characters except the following: alphabetic, decimal digits, - _ . ! ~ * ' ( )
     * 
     * @param input
     *            A component of a URI
     * @return the escaped URI component
     */
    public static String encodeURIComponent(String input)
    {
        if (input == null)
        {
            return input;
        }

        StringBuilder filtered = new StringBuilder(input.length());
        char c;
        for (int i = 0; i < input.length(); ++i)
        {
            c = input.charAt(i);
            if (dontNeedEncoding.get(c))
            {
                filtered.append(c);
            }
            else
            {
                final byte[] b = charToBytesUTF(c);

                for (int j = 0; j < b.length; ++j)
                {
                    filtered.append('%');
                    filtered.append("0123456789ABCDEF".charAt(b[j] >> 4 & 0xF));
                    filtered.append("0123456789ABCDEF".charAt(b[j] & 0xF));
                }
            }
        }
        return filtered.toString();
    }

    private static byte[] charToBytesUTF(char c)
    {
        try
        {
            return new String(new char[] { c }).getBytes("UTF-8");
        }
        catch (UnsupportedEncodingException e)
        {
            return new byte[] { (byte) c };
        }
    }
}

একটি ভাল সমাধানের জন্য ধন্যবাদ! অন্যরা পুরোপুরি ... অদক্ষ দেখতে, আইএমও। সম্ভবত এটি আজকের হার্ডওয়্যারে বিটসেট ছাড়াই আরও ভাল। অথবা 0 ... 127 এর জন্য দুটি হার্ড-কোডেড লম্বা।
জোনাস এন

URLEncoder.encode("+", "UTF-8");ফলন "%2B", যা সঠিক URL এনকোডিং, তাই আপনার সমাধানটি হ'ল আমার ক্ষমা, সম্পূর্ণ অপ্রয়োজনীয়। পৃথিবীতে URLEncoder.encodeস্থান কেন স্থানগুলিতে পরিণত %20হয় না তা আমার বাইরে।
2rs2ts


1

আমি জাভা.net. ইউআরআই ক্লাসটি সফলভাবে ব্যবহার করেছি:

public static String uriEncode(String string) {
    String result = string;
    if (null != string) {
        try {
            String scheme = null;
            String ssp = string;
            int es = string.indexOf(':');
            if (es > 0) {
                scheme = string.substring(0, es);
                ssp = string.substring(es + 1);
            }
            result = (new URI(scheme, ssp, null)).toString();
        } catch (URISyntaxException usex) {
            // ignore and use string that has syntax error
        }
    }
    return result;
}

নাহ, এটি এই পদ্ধতির সম্পূর্ণ সফল নয় তবে এটি তুলনামূলকভাবে ঠিক relatively আপনার এখনও সমস্যা আছে। উদাহরণস্বরূপ, কার্ডিনাল চরিত্র # জাভা% 23 এ এনকোড হবে জাভাস্ক্রিপ্ট এটি এনকোড করবে না। দেখুন: বিকাশকারী.মোজিলা.আর.ইন- ইউএস / ডকস / ওয়েবে / জাভা স্ক্রিপ্ট / রেফারেন্স /… জাভাস্ক্রিপ্ট স্পেস করে না। এজেড এজে 0-9; , /? : @ & = + $ - _। ! ~ * '() # এবং এর মধ্যে কয়েকটি জাভা স্পেস করবে।
99 সোনো

নিম্নলিখিত এক্সপ্রেশন দিয়ে একটি ইউএনআইটি পরীক্ষা করে ভাল জিনিস: '' 'স্ট্রিং অক্ষর জাভাস্ক্রিপ্টডনস নটস্পেস = "এ-জা-জেড -00 -9;, /?: @ & = + $ -_।! ~ *' () #"; '' 'কার্ডিনাল একমাত্র আউটলেটর। সুতরাং এটি জাভাস্ক্রিপ্টের সাথে সামঞ্জস্যপূর্ণ করতে উপরের অ্যালগরিদম ঠিক করা তুচ্ছ v
99 সোনো

1

এটি একটি সহজ উদাহরণ রবি ওয়ালাউয়ের সমাধান:

public String buildSafeURL(String partialURL, String documentName)
        throws ScriptException {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine scriptEngine = scriptEngineManager
            .getEngineByName("JavaScript");

    String urlSafeDocumentName = String.valueOf(scriptEngine
            .eval("encodeURIComponent('" + documentName + "')"));
    String safeURL = partialURL + urlSafeDocumentName;

    return safeURL;
}

public static void main(String[] args) {
    EncodeURIComponentDemo demo = new EncodeURIComponentDemo();
    String partialURL = "https://www.website.com/document/";
    String documentName = "Tom & Jerry Manuscript.pdf";

    try {
        System.out.println(demo.buildSafeURL(partialURL, documentName));
    } catch (ScriptException se) {
        se.printStackTrace();
    }
}

আউটপুট: https://www.website.com/document/Tom%20%26%20Jerry%20Manuscript.pdf

এটি স্ট্রিং ভেরিয়েবল কীভাবে পাস করবেন সে সম্পর্কে লরেন শকিপাগনজার মন্তব্যে ঝুলন্ত প্রশ্নের উত্তর দেয় encodeURIComponent()। পদ্ধতিটি scriptEngine.eval()ফেরত দেয় Object, তাই এটি String.valueOf()অন্যান্য পদ্ধতির মধ্যে দিয়ে স্ট্রিংয়ে রূপান্তর করতে পারে ।


1

আমার জন্য এটি কাজ করেছে:

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

String encodedString = new URIBuilder()
  .setParameter("i", stringToEncode)
  .build()
  .getRawQuery() // output: i=encodedString
  .substring(2);

বা অন্য একটি ইউরিবিল্ডার সহ

import javax.ws.rs.core.UriBuilder;

String encodedString = UriBuilder.fromPath("")
  .queryParam("i", stringToEncode)
  .toString()   // output: ?i=encodedString
  .substring(3);

আমার মতে স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করা ম্যানুয়ালি পোস্ট প্রসেসিংয়ের চেয়ে ভাল ধারণা। এছাড়াও @ ক্রিস উত্তরটি দেখতে ভাল লাগছিল, তবে এটি " http: // a + b c.html" এর মতো ইউআরএলগুলির জন্য কাজ করে না


4
স্ট্যান্ডার্ড লাইব্রেরিটি ব্যবহার করা ভাল ... ... যদি না আপনি মাঝারি জিনিসপত্র হন এবং মানক গ্রন্থাগারের বিভিন্ন সংস্করণের উপর নির্ভর করেন না, এবং তারপরে আপনার কোড ব্যবহার করা যে কোনও ব্যক্তিকে নির্ভরতার সাথে বেঁধে ফেলতে হবে, এবং তারপরে কিছুই ভাঙার আশা নেই ...
অ্যাজাক্স

এই সমাধানটি যদি কাজ করে তবে দুর্দান্ত হবে তবে এটি অনুরোধের মতো আচরণ করে না encodeURIComponent। ফলাফলের encodeURIComponentজন্য ফিরে আসে , কিন্তু আপনার পরামর্শ ফিরে আসে । আমি জানি অন্যান্য প্রশ্ন এবং উত্তরগুলিতে এটি একাধিকবার উল্লেখ করা হয়েছে, তবে লোকেদের অন্ধভাবে বিশ্বাস করার আগে এটি এখানে উল্লেখ করা উচিত। ?& %3F%26%20%3F%26+
ফিলিপ

1

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

private static final String HEX = "0123456789ABCDEF";

public static String encodeURIComponent(String str) {
    if (str == null) return null;

    byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
    StringBuilder builder = new StringBuilder(bytes.length);

    for (byte c : bytes) {
        if (c >= 'a' ? c <= 'z' || c == '~' :
            c >= 'A' ? c <= 'Z' || c == '_' :
            c >= '0' ? c <= '9' :  c == '-' || c == '.')
            builder.append((char)c);
        else
            builder.append('%')
                   .append(HEX.charAt(c >> 4 & 0xf))
                   .append(HEX.charAt(c & 0xf));
    }

    return builder.toString();
}

এটি আরএফসি 3986 অনুসারে কোনও অক্ষর নয় এমন প্রতিটি চরিত্রকে শতাংশ-এনকোডিং করে জাভাস্ক্রিপ্টের ছাড়িয়ে গেছে ।


এটি অপোসাইট রূপান্তর:

public static String decodeURIComponent(String str) {
    if (str == null) return null;

    int length = str.length();
    byte[] bytes = new byte[length / 3];
    StringBuilder builder = new StringBuilder(length);

    for (int i = 0; i < length; ) {
        char c = str.charAt(i);
        if (c != '%') {
            builder.append(c);
            i += 1;
        } else {
            int j = 0;
            do {
                char h = str.charAt(i + 1);
                char l = str.charAt(i + 2);
                i += 3;

                h -= '0';
                if (h >= 10) {
                    h |= ' ';
                    h -= 'a' - '0';
                    if (h >= 6) throw new IllegalArgumentException();
                    h += 10;
                }

                l -= '0';
                if (l >= 10) {
                    l |= ' ';
                    l -= 'a' - '0';
                    if (l >= 6) throw new IllegalArgumentException();
                    l += 10;
                }

                bytes[j++] = (byte)(h << 4 | l);
                if (i >= length) break;
                c = str.charAt(i);
            } while (c == '%');
            builder.append(new String(bytes, 0, j, UTF_8));
        }
    }

    return builder.toString();
}

0

আমি গুগল-এইচপি-জাভা-ক্লায়েন্ট লাইব্রেরি থেকে পার্সেন্টএস্কেটার ক্লাস পেয়েছি, যা এনকোডেরিকআউমিকম্পোনেন্টটি সহজেই প্রয়োগ করতে ব্যবহার করা যেতে পারে।

গুগল-এইচপি-জাভা-ক্লায়েন্ট জাভাদোক গুগল- এইচপি -জাভা-ক্লায়েন্ট হোম থেকে শতাংশ শতাংশ


0

পেয়ারা লাইব্রেরিতে পার্সেন্টইস্কার রয়েছে:

Escaper percentEscaper = new PercentEscaper("-_.*", false);

"-_। *" নিরাপদ অক্ষর

মিথ্যা বলছে '%' দিয়ে স্থান + "+" নয়, পালাতে পার্সেন্টস্কর


0

আমি String encodedUrl = new URI(null, url, null).toASCIIString(); ইউআরএলগুলি এনকোড করতাম । urlআমি ব্যবহার করি বিদ্যমান বিদ্যমানগুলির পরে পরামিতি যুক্ত করতেUriComponentsBuilder

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