Aplikasi Java mandiri saya mendapat URL (yang menunjuk ke suatu file) dari pengguna dan saya perlu menekan dan mengunduhnya. Masalah yang saya hadapi adalah saya tidak dapat menyandikan alamat URL HTTP dengan benar ...
Contoh:
URL: http://search.barnesandnoble.com/booksearch/first book.pdf
java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");
mengembalikan saya:
http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf
Tapi, yang saya inginkan adalah
http://search.barnesandnoble.com/booksearch/first%20book.pdf
(ruang diganti oleh% 20)
saya tebak URLEncoder
tidak dirancang untuk menyandikan URL HTTP ... JavaDoc mengatakan "Kelas utilitas untuk penyandian formulir HTML" ... Apakah ada cara lain untuk melakukan ini?
Jawaban:
Kelas java.net.URI dapat membantu; dalam dokumentasi URL yang Anda temukan
Gunakan salah satu konstruktor dengan lebih dari satu argumen, seperti:
(konstruktor argumen tunggal URI TIDAK lepas dari karakter ilegal)
Hanya karakter ilegal yang lolos dengan kode di atas - ia TIDAK lepas dari karakter non-ASCII (lihat komentar fatih).
The
toASCIIString
metode dapat digunakan untuk mendapatkan String hanya dengan karakter US-ASCII:Untuk URL dengan kueri suka
http://www.google.com/ig/api?weather=São Paulo
, gunakan versi 5-parameter dari konstruktor:sumber
java.net.URI
: ia bekerja dengan sempurna (Java 1.6). Saya akan menyebutkan nama kelas yang sepenuhnya memenuhi syarat jika itu bukan Java standar dan tautan menunjuk ke dokumentasijava.net.URI
. Dan, dengan komentar Sudhakar, itu memecahkan masalah tanpa menyertakan "perpustakaan umum"!Harap diingat bahwa sebagian besar jawaban di atas tidak benar.
The
URLEncoder
kelas, meskipun nama, adalah bukan apa yang perlu di sini. Sangat disayangkan Sun menamakan kelas ini dengan sangat menyebalkan.URLEncoder
dimaksudkan untuk meneruskan data sebagai parameter, bukan untuk menyandi URL itu sendiri.Dengan kata lain,
"http://search.barnesandnoble.com/booksearch/first book.pdf"
adalah URL. Parameter akan, misalnya"http://search.barnesandnoble.com/booksearch/first book.pdf?parameter1=this¶m2=that"
,. Parameternya adalah apa yang akan Anda gunakanURLEncoder
.Dua contoh berikut menyoroti perbedaan di antara keduanya.
Berikut ini menghasilkan parameter yang salah, sesuai dengan standar HTTP. Perhatikan bahwa ampersand (&) dan plus (+) dikodekan secara salah.
Berikut ini akan menghasilkan parameter yang benar, dengan kueri disandikan dengan benar. Perhatikan spasi, tanda bintang, dan tanda plus.
sumber
query = URLEncoder.encode(key) + "=" + URLEncoder.encode(value)
. Dokumen hanya mengatakan bahwa "karakter apa pun yang bukan karakter URI legal dikutip".Saya akan menambahkan satu saran di sini yang ditujukan untuk pengguna Android. Anda dapat melakukan ini yang menghindari keharusan mendapatkan perpustakaan eksternal. Selain itu, semua solusi pencarian / penggantian karakter yang disarankan dalam beberapa jawaban di atas berbahaya dan harus dihindari.
Cobalah ini:
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 pencarian string / mengganti pekerjaan. 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 memerlukan pengetahuan khusus tentang itu sendiri.
sumber
#
.solusi yang saya kembangkan dan jauh lebih stabil daripada yang lain:
sumber
String utf8Input = new String(Charset.forName("UTF-8").encode(input).array());
(diambil dari sini )Jika Anda memiliki URL, Anda dapat mengirimkan url.toString () ke metode ini. Dekode pertama, untuk menghindari penyandian ganda (misalnya, penyandian ruang menghasilkan% 20 dan penyandian tanda persen menghasilkan% 25, jadi penyandian ganda akan mengubah ruang menjadi% 2520). Kemudian, gunakan URI seperti dijelaskan di atas, menambahkan semua bagian URL (sehingga Anda tidak menjatuhkan parameter kueri).
sumber
Ya penyandian URL akan menyandikan string itu sehingga akan diteruskan dengan benar di url ke tujuan akhir. Misalnya Anda tidak dapat memiliki http://stackoverflow.com?url=http://yyy.com . UrlEncoding parameter akan memperbaiki nilai parameter itu.
Jadi saya punya dua pilihan untuk Anda:
Apakah Anda memiliki akses ke jalur yang terpisah dari domain? Jika demikian, Anda mungkin dapat dengan mudah UrlEncode the path. Namun, jika ini bukan masalahnya maka opsi 2 mungkin cocok untuk Anda.
Dapatkan commons-httpclient-3.1. Ini memiliki kelas URIUtil:
System.out.println (URIUtil.encodePath (" http://example.com/x y", "ISO-8859-1"));
Ini akan menampilkan apa yang Anda cari, karena hanya akan menyandikan bagian jalur URI.
FYI, Anda akan memerlukan commons-codec dan commons-logging untuk metode ini agar berfungsi saat runtime.
sumber
URIUtil
solusiNitpicking: string yang berisi karakter spasi putih menurut definisi bukan URI. Jadi yang Anda cari adalah kode yang mengimplementasikan pelolosan URI yang didefinisikan dalam Bagian 2.1 dari RFC 3986 .
sumber
Sayangnya,
org.apache.commons.httpclient.util.URIUtil
sudah usang, danreplacement org.apache.commons.codec.net.URLCodec
apakah pengkodean cocok untuk posting bentuk, bukan di URL yang sebenarnya. Jadi saya harus menulis fungsi saya sendiri, yang melakukan komponen tunggal (tidak cocok untuk seluruh string kueri yang dimiliki? 'Dan &' s)sumber
URLEncoding dapat menyandikan URL HTTP dengan baik, seperti yang sayangnya Anda temukan. String yang Anda masukkan, " http://search.barnesandnoble.com/booksearch/first book.pdf", telah dikodekan dengan benar dan sepenuhnya ke dalam bentuk yang disandikan URL. Anda bisa meneruskan seluruh rangkaian panjang gobbledigook yang Anda dapatkan kembali sebagai parameter dalam URL, dan itu bisa didekodekan kembali menjadi string yang Anda lewati.
Sepertinya Anda ingin melakukan sesuatu yang sedikit berbeda daripada meneruskan seluruh URL sebagai parameter. Dari apa yang saya kumpulkan, Anda mencoba membuat URL pencarian yang terlihat seperti " http://search.barnesandnoble.com/booksearch/wh whateverTheUserPassesIn ". Satu-satunya hal yang perlu Anda enkode adalah bit "whateverTheUserPassesIn", jadi mungkin yang perlu Anda lakukan adalah sesuatu seperti ini:
Itu akan menghasilkan sesuatu yang lebih valid untuk Anda.
sumber
Jika ada yang tidak ingin menambahkan ketergantungan pada proyek mereka, fungsi-fungsi ini mungkin bermanfaat.
Kami melewati bagian 'jalur' dari URL kami ke sini. Anda mungkin tidak ingin meneruskan URL lengkap sebagai parameter (string kueri perlu escapes yang berbeda, dll).
Dan tes:
sumber
Masih ada masalah jika Anda memiliki kode "/" (% 2F) yang disandikan di URL Anda.
RFC 3986 - Bagian 2.2 mengatakan: "Jika data untuk komponen URI akan bertentangan dengan tujuan karakter yang dicadangkan sebagai pembatas, maka data yang bertentangan harus dikodekan persen sebelum URI dibentuk." (RFC 3986 - Bagian 2.2)
Tapi ada Masalah dengan Tomcat:
Jadi, jika Anda memiliki URL dengan karakter% 2F, Tomcat mengembalikan: "400 URI tidak valid: noSlash"
Anda dapat beralih dari perbaikan bug di skrip startup Tomcat:
sumber
Saya membaca jawaban sebelumnya untuk menulis metode saya sendiri karena saya tidak dapat melakukan sesuatu dengan benar menggunakan solusi dari jawaban sebelumnya, itu terlihat bagus untuk saya tetapi jika Anda dapat menemukan URL yang tidak berfungsi dengan ini, beri tahu saya.
sumber
Saya setuju dengan Matt. Memang, saya belum pernah melihatnya dengan baik dijelaskan dalam tutorial, tetapi satu hal adalah bagaimana menyandikan jalur URL, dan yang sangat berbeda adalah bagaimana menyandikan parameter yang ditambahkan ke URL (bagian permintaan, di belakang "? " simbol). Mereka menggunakan pengkodean yang serupa, tetapi tidak sama.
Khusus untuk pengkodean karakter spasi putih. Jalur URL harus dikodekan sebagai% 20, sedangkan bagian kueri memungkinkan% 20 dan juga tanda "+". Ide terbaik adalah mengujinya sendiri terhadap server Web kami, menggunakan browser Web.
Untuk kedua kasus, saya SELALU akan menyandikan KOMPONEN DENGAN KOMPONEN , tidak pernah seluruh string. Memang URLEncoder memungkinkan itu untuk bagian permintaan. Untuk bagian jalur Anda bisa menggunakan kelas URI, meskipun dalam kasus ini meminta seluruh string, bukan komponen tunggal.
Bagaimanapun, saya percaya bahwa cara terbaik untuk menghindari masalah ini adalah dengan menggunakan desain pribadi yang tidak konflik. Bagaimana? Sebagai contoh, saya tidak akan pernah memberi nama direktori atau parameter menggunakan karakter lain selain aZ, AZ, 0-9 dan _. Dengan begitu, satu-satunya kebutuhan adalah menyandikan nilai setiap parameter, karena mungkin berasal dari input pengguna dan karakter yang digunakan tidak diketahui.
sumber
Mungkin dapat mencoba UriUtils di org.springframework.web.util
sumber
Anda juga dapat menggunakan
GUAVA
dan mengarahkan escaper:UrlEscapers.urlFragmentEscaper().escape(relativePath)
sumber
Selain balasan Carlos Heuberger: jika diperlukan perbedaan dari standar (80), konstruktor 7 param harus digunakan:
sumber
Saya mengambil konten di atas dan mengubahnya sedikit. Saya suka logika positif terlebih dahulu, dan saya pikir HashSet mungkin memberikan kinerja yang lebih baik daripada beberapa opsi lain, seperti mencari melalui String. Meskipun, saya tidak yakin apakah penalti autoboxing sepadan, tetapi jika kompiler mengoptimalkan untuk karakter ASCII, maka biaya tinju akan rendah.
sumber
Gunakan solusi Java standar berikut (melewati 100 testcases yang disediakan oleh Web Plattform Tests ):
0. Uji apakah URL sudah dikodekan .
1. Pisahkan URL menjadi bagian-bagian struktural. Gunakan
java.net.URL
untuk itu.2. Encode setiap bagian struktural dengan benar!
3. Gunakan
IDN.toASCII(putDomainNameHere)
untuk Punycode menyandikan nama host!4. Gunakan
java.net.URI.toASCIIString()
untuk persen-encode, NFC dikodekan unicode - (lebih baik NFKC!).Temukan lebih lanjut di sini: https://stackoverflow.com/a/49796882/1485527
sumber
Saya telah membuat proyek baru untuk membantu membangun URL HTTP. Perpustakaan akan secara otomatis menyandi URL segmen jalan dan parameter kueri.
Anda dapat melihat sumber dan mengunduh biner di https://github.com/Widen/urlbuilder
Contoh URL dalam pertanyaan ini:
menghasilkan
http://search.barnesandnoble.com/booksearch/first%20book.pdf
sumber
Saya memiliki masalah yang sama. Selesaikan ini dengan tidak:
Ini mengkodekan string tetapi melompat ":" dan "/".
sumber
saya menggunakan ini
tambahkan ketergantungan ini
sumber
Saya mengembangkan perpustakaan yang melayani tujuan ini: galimatias . Ini mem-parsing URL dengan cara yang sama seperti browser web. Artinya, jika URL berfungsi di browser, URL akan diurai dengan benar oleh galimatias .
Pada kasus ini:
Akan memberikan:
http://search.barnesandnoble.com/booksearch/first%20book.pdf
. Tentu saja ini adalah kasus yang paling sederhana, tetapi ini akan berhasil dengan apa pun, jauh dari itujava.net.URI
.Anda dapat memeriksanya di: https://github.com/smola/galimatias
sumber
Anda dapat menggunakan fungsi seperti ini. Lengkapi dan modifikasi sesuai kebutuhan Anda:
Contoh penggunaan:
Hasilnya adalah: http://www.growup.com/folder/int%C3%A9rieur-%C3%A0_vendre?o=4
sumber
String url = "" http://search.barnesandnoble.com/booksearch/ ;
Ini akan menjadi konstan saya kira dan hanya perubahan nama file secara dyamically jadi dapatkan nama file
Nama file string; // dapatkan nama file
String urlEnc = url + fileName.replace ("", "% 20");
sumber
Bagaimana tentang:
UrlEncode String publik (String in_) {
}
sumber