Pengkodean URL di Android

336

Bagaimana Anda menyandikan URL di Android?

Saya pikir itu seperti ini:

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

Jika saya melakukan hal di atas, http://in urlAsStringdigantikan oleh http%3A%2F%2Fin encodedURLdan kemudian saya dapatkan java.net.MalformedURLExceptionketika saya menggunakan URL.

hpique
sumber

Jawaban:

630

Anda tidak menyandikan seluruh URL, hanya sebagian yang berasal dari "sumber tidak dapat diandalkan".

String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;

Atau, Anda dapat menggunakan Strings.urlEncode (String str) dari DroidParts yang tidak membuang pengecualian yang diperiksa.

Atau gunakan sesuatu seperti

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();
yanchenko
sumber
1
Bagaimana jika seluruh url tidak dapat diandalkan? Haruskah saya menyandikan semuanya kecuali protokol? Saya agak berharap metode kenyamanan untuk melakukan ini.
hpique
5
Maka itu hanya url yang rusak. Idenya adalah untuk mencegah bagian permintaan dari melanggar url.
yanchenko
5
@hgpc - lihat bagian 3 dari RFC3986 ( tools.ietf.org/html/rfc3986#section-3 ). Ini memberi tahu Anda cara menyandikan berbagai bagian URI. Sayangnya setiap bagian dari URI (host, path, query, dll.) Memiliki aturan penyandian yang sedikit berbeda.
D.Shawley
2
Ini bagus karena Anda hanya berurusan dengan bagian tertentu dari URL dan Anda tahu cara membuat atau merekonstruksi URL. Untuk pendekatan yang lebih umum yang dapat menangani string url, lihat jawaban saya di bawah ini.
Craig B
8
Mengapa saya mendapatkan peringatan penghentian menggunakan ini? Digunakan Uri.encode(query);sebagai gantinya.
prasanthv
166

Saya akan menambahkan satu saran di sini. Anda dapat melakukan ini yang menghindari keharusan mendapatkan perpustakaan eksternal.

Cobalah ini:

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

Anda dapat melihat bahwa di URL khusus ini, saya harus memiliki ruang-ruang yang disandikan agar saya dapat menggunakannya untuk permintaan.

Ini memanfaatkan beberapa fitur yang tersedia untuk Anda di kelas Android. Pertama, kelas URL dapat memecah url menjadi komponen yang tepat sehingga Anda tidak perlu melakukan pekerjaan pencarian / penggantian string. Kedua, pendekatan ini mengambil keuntungan dari fitur kelas URI dari komponen yang lolos dengan benar ketika Anda membangun URI melalui komponen daripada dari string tunggal.

Keindahan dari pendekatan ini adalah bahwa Anda dapat mengambil string url yang valid dan membuatnya bekerja tanpa perlu pengetahuan khusus tentang itu sendiri.

Craig B
sumber
19
Ini seharusnya jawaban yang benar. ini adalah cara formal dan jelas untuk melakukan ini
Asanka Senavirathna
3
Ini juga merupakan ide yang bagus untuk urldecode urlStr sebelum mengirimnya ke konstruktor URL. URLDecoder.decode (urlStr)
Jakob Eriksson
1
Terima kasih untuk posting :) Tapi saya menghadapi masalah. Jika url sudah disandikan sebagian, berarti penyandian bagian yang sudah disandikan. Apa yang harus saya lakukan? Misalnya: dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/...% 20 dikodekan ke% 2520
mengamuk
2
@berserk Jika sudah disandikan, jangan disandikan. Anda seharusnya tidak masuk ke kondisi di mana sebagian dikodekan, atau Anda tidak yakin apakah itu dikodekan atau tidak.
Marquis of Lorne
3
Metode ini tidak menyandikan karakter seperti ğ ke% C4% 9F. Satu encode yang diterima!
Alexander Prokofyev
74

Untuk android, saya akan menggunakan String android.net.Uri.encode (String s)

Mengkode karakter dalam string yang diberikan sebagai '%' - lolos oktet menggunakan skema UTF-8. Meninggalkan huruf ("AZ", "az"), angka ("0-9"), dan karakter yang tidak disimpan ("_- !. ~ '() *"). Mengkodekan semua karakter lain.

Ex/

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);
tanutapi
sumber
2
Sayangnya Uri.encode("a=1&b=1")menghasilkan a%3D1%26b%3D1tetapi diharapkana=1&b=1
loentar
14
@lentar Itulah hasil yang diharapkan. Jika pengguna memasukkan a=1&b=1sebagai kueri, Anda ingin menanyakannya dengan tepat.
Anubian Noob
Betapa berbedanya ini dengan URLEncoder.encode (StringHere, "UTF-8")
stuckedoverflow
@stuckedoverflow Untuk satu hal, Uri.encode (str) tidak melempar pengecualian yang diperiksa tidak seperti URLEncoder.encode (str, "UTF-8")
deekshith
50

Anda juga dapat menggunakan ini

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

itu metode yang paling sederhana

Jedo
sumber
1
ini bukan solusi terbaik, tapi ini jelas merupakan perbaikan cepat yang bagus ... thanx
Sebastian Breit
4
Ini adalah perbaikan tercepat ketika seluruh URL tidak dapat diandalkan. Terima kasih!
user1032613
Apakah Anda yakin% harus diizinkan? Haruskah itu tidak dikodekan?
MediumOne
1
Bagaimana menyandikan url ini agar memungkinkan untuk dibagikan dan kemudian pengguna dapat membuka tautan dan melihat halaman: yazd20.com//News/2015/id
Ahmad Ebrahimi
3
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
Joolah
sumber
1

Anda dapat menggunakan metode di bawah ini

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

atau

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

yang kedua lebih baik dari yang pertama.

Elango
sumber
0

Temukan karakter bahasa Arab dan gantikan dengan pengkodean UTF-8. sesuatu seperti ini:

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;
Ali Jafari
sumber