Apa itu Upload File?
Unggah file adalah untuk menyimpan informasi pengguna.
Mengapa saya perlu mengunggah file?
Ketika pengguna mendaftar, pengguna mungkin perlu mengirimkan foto. Maka foto ini harus disimpan.
Unggah komponen (alat) Mengapa kita perlu menggunakan alat unggahan?
Mengapa kita perlu mengunggah komponen? Ketika kami ingin mendapatkan data klien, kami biasanya mendapatkannya melalui metode getParameter ().
Data file yang diunggah dibagi dengan protokol MIME, dan formulir ini dienkapsulasi dalam biner. Dengan kata lain: getParameter () tidak bisa mendapatkan data dari file yang diunggah.
Mari kita lihat bagaimana unggahan file http membawa data bersama Anda
Halaman JSP, Formulir Harus Menentukan Enctype: Multipart/Form-Data
<Form Action = "$ {pageContext.Request.contextPath}/servlet/unggah servet1" enctype = "multipart/form-data" method = "post"> Unggah Pengguna: <input type = "name =" Username "> <br/> unggah file 1: <input type =" file "name =" username "> <br/> unggah file 1: <input type =" file "name =" username " name = "file2"> <br/> <input type = "kirim" value = "kirim"> </form>Paket http meraih
Cobalah untuk mendapatkan data menggunakan getParameter () di servlet
String ss = request.getParameter ("nama pengguna"); System.out.println (ss);Anda tidak bisa mendapatkan data dengan langsung menggunakan getParameter.
Jadi apa yang harus kita lakukan? ? ? ? Objek permintaan menyediakan aliran servletInputStream untuk membaca data kepada kami
Kami mencoba membaca file
ServletInputStream inputStream = request.getInputStream (); byte [] bytes = byte baru [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {System.out.println (string baru (bytes, 0, len)); }Tambahkan kontrol input tambahan ke halaman JSP
<input type = "text" name = "password">
File teks yang saya unggah adalah 111111, dan efek membaca adalah sebagai berikut:
Sekarang kita dapat membaca data pengunggahan file, tetapi sekarang pertanyaannya adalah: Bagaimana cara memisahkan data file yang diunggah dari data yang dikirim ke server? ? ? Kami telah melihat di atas dalam gambar, mereka dicampur bersama.
Sulit untuk terpisah sesuai dengan praktik kami yang biasa, jadi kami perlu mengunggah komponen
Ada dua jenis komponen unggahan fileuploads [lebih banyak operasi] samrTupload [lebih banyak operasi] Fileupload
Untuk menggunakan komponen Fileupload, Anda perlu mengimpor dua paket JAR
Commons-OO Commons-Fileupload Langkah-langkah Membuat Objek Pabrik Parser [DiskFileItemFactory] Buat parser melalui pabrik parser [servletfileupload] hubungi metode parser untuk menguraikan objek permintaan, dapatkan semua konten yang diunggah [daftar] melintasi daftar, tentukan apakah setiap objek adalah file yang diunggah. Jika itu adalah bidang bentuk normal, dapatkan nama bidang dan nilai bidang. Jika itu adalah file yang diunggah, hubungi metode inputSteam untuk mendapatkan aliran input, baca data yang diunggah dengan cepat.
coba {// 1. Dapatkan Parser Factory DiskFileItemFactory Factory = New DiskFileItemFactory (); // 2. Dapatkan Parser ServletFileUpload Upload = NEW SERVLETFILEUPLOAD (pabrik); // 3. Tentukan jenis formulir pengunggahan IF (! Upload.ismultipartContent (permintaan)) {// Unggah formulir adalah formulir normal, kemudian dapatkan data dengan cara tradisional untuk kembali; } // Untuk mengunggah formulir, hubungi parser untuk mem -parsing daftar data yang diunggah <FILEITEM> DAFTAR = UEDLOAD.PARSEREQUEST (permintaan); // FileItem // Transfusikan daftar dan dapatkan objek FileItem yang digunakan untuk merangkum Objek Input Input Item Input FileItem pertama untuk (FileItem Item: List) {if (item.isFormField ()) {// Apa yang Anda dapatkan adalah item input normal name string = item.getfieldName (); // Dapatkan nama nilai input item string value = item.getString (); System.out.println (name + "=" + value); } else {// dapatkan unggah item input string fileName = item.getName (); // Dapatkan nama file unggahan c:/dokumen dan pengaturan/thinkpad/desktop/1.txt filename = filename.substring (filename.lastIndexof ("//")+1); InputStream in = item.getInputStream (); // Dapatkan unggah data int len = 0; byte buffer [] = byte baru [1024]; String savePath = this.getSerVletContext (). GetRealPath ("/unggah"); FileOutputStream out = FileOutputStream baru (savePath + "//" + fileName); // Tulis file ke direktori unggah while ((len = in.read (buffer))> 0) {out.write (buffer, 0, len); } in.close (); out.close (); }}} catch (Exception e) {e.printstacktrace (); }Menguji bahwa kedua bidang biasa dan file yang diunggah dapat dibaca dan diperoleh!
Smartupload
Untuk menggunakan komponen Smartupload, Anda perlu mengimpor paket pengembangan Smartupload.jar
Awal yang cepat
// komponen instantiated Smartupload smartupload = new Smartupload (); // inisialisasi operasi unggah smartupload.initialize (this.getServletConfig (), permintaan, respons); coba {// unggah persiapan smartupload.upload (); // Untuk data biasa, sangat sederhana sehingga objek permintaan tidak dapat memperoleh parameter yang dikirimkan. Juga, Anda harus mengandalkan Smartupload String Password = Smartupload.getRequest (). GetParameter ("Kata Sandi"); System.out.println (kata sandi); // Unggah ke folder unggah smartupload.save ("unggahfile"); } catch (SmartuploAdException e) {e.printstacktrace (); }tes
Demikian pula, kami dapat mengunggah file ke folder unggahan. Jumlah kode memang berkurang banyak!
Anda juga bisa mendapatkan parameter bidang normal
Saya mengubah nama file menjadi kode kacau Cina dan kode kacau Cina untuk mengunggah data, dan itu adalah kode yang kacau:
Data Cina yang diajukan oleh formulir juga kacau.
Seperti disebutkan di atas, bentuk pengunggahan data file dienkapsulasi dalam biner, jadi menggunakan permintaan untuk menyandikan data tidak akan berfungsi untuk data yang dikirimkan oleh formulir!
Fileupload memecahkan kode yang kacau
Menggunakan Fileupload untuk Memecahkan Masalah Terkocok sangat sederhana
Selesaikan nama file Cina yang kacau. Setelah mendapatkan parser, cukup atur pengkodean parser ke UTF-8!
// Atur pengkodean unggahan fileupload.setHeaderencoding ("UTF-8");Selesaikan data formulir yang kacau. Saat mendapatkan nilai formulir, gunakan pengkodean UTF-8 untuk mendapatkannya.
String value = FileItem.getString ("UTF-8");Memengaruhi:
Smartupload memecahkan kode yang kacau
Komponen ini agak merepotkan untuk menyelesaikan masalah kode yang kacau. Saya menemukan berbagai solusi online tetapi tidak dapat menemukan yang sederhana ...
Oleh karena itu, jika data tidak melibatkan bahasa Mandarin, gunakan komponen Smartupload, dan jika melibatkan data Cina, gunakan komponen Fileupload!
Unggah banyak file, tambahkan kontrol unggahan secara dinamis
Misalkan saya memiliki beberapa file untuk diunggah sekarang, dan jumlah file yang harus diunggah tidak pasti. Jadi apa yang harus kita lakukan? ? ?
Tidak mungkin bagi kita untuk membuat daftar banyak kontrol untuk mengunggah file pada halaman, yang tidak indah. Jika pengguna tidak dapat menggunakan begitu banyak kontrol, itu sia -sia.
Oleh karena itu, kami ingin secara dinamis menambahkan kontrol untuk mengunggah file. Jika pengguna juga ingin mengunggah file, ia hanya perlu menghasilkan kontrol secara dinamis!
menganalisa
Untuk menghasilkan kontrol secara dinamis pada halaman, tidak lebih dari menggunakan kode JavaScript.
Jadi apa yang kita lakukan? ?
Mari kita lakukan ini: Ketika pengguna ingin mengunggah file, klik tombol, dan tombol mengikat acara untuk menghasilkan kontrol untuk mengunggah file.
Untuk melakukan lebih sempurna, setiap kali kontrol unggahan file dihasilkan, tombol hapus juga disediakan untuk menghapus kontrol!
Kita harus menggunakan DIV untuk memuat kontrol dan menghapus tombol yang ingin kita hasilkan. Ketika pengguna mengklik untuk menghapus, mereka harus menyembunyikan tombol Hapus dan mengunggah file kontrol bersama -sama. Jadi, yang terbaik adalah menggunakan Divs bersarang!
Kode Halaman Kode:
<table> <tr> <td>Upload user: </td> <td><input type="text" name="username"></td> </tr> <tr> <td>Add upload file</td> <td><input type="button" value="Add upload file"> </td> </tr> <tr> <td> <div> </div> </td> </td> </tr> </able>
Kode JavaScript
<script type = "text/javaScript"> function adduploadFile () {// menghasilkan kontrol unggahan file var input = document.createElement ("input"); input.type = 'file'; input.name = 'nama file'; // Hasilkan tombol hapus var del = document.createElement ("input"); del.type = 'tombol'; del.value = 'hapus'; // menghasilkan internal div var innerdiv = document.createElement ("div"); // ikat dua kontrol ke innerdiv.appendchild (input); innerdiv.appendchild (del); // Dapatkan kontrol div eksternal dan ikat div internal ke div eksternal var outterdiv = document.getElementById ("file"); OutterDiv.AppendChild (Innerdiv); // bind event del.onClick = function delete () {// Memanggil metode hapus dari div eksternal untuk membunuh div internal this.parentnode.parentnode.removechild (this.parentnode); }} </script>File Unggah Detail Jika ukuran file yang diunggah lebih besar dari ukuran file yang kami atur, maka file akan menggunakan file sementara untuk menyimpan data yang diunggah saat mengunggah. Setelah mengunggah, kita harus menghapus file sementara. Lokasi di mana file unggahan tidak dapat dikelola oleh server web, jika tidak, ia dapat menyebabkan masalah keamanan [orang lain dapat memodifikasi file unggahan melalui cara] jika nama file unggahannya sama, file unggahan asli akan ditimpa. Kami ingin menghasilkan nama file yang unik. Jika jumlah pengguna besar, ada banyak file yang diunggah. Maka kita tidak boleh menyimpan semua file unggahan dalam satu direktori, yang kemungkinan akan menyebabkan disk macet. Jadi kita harus membubarkan file yang diunggah ke direktori yang berbeda. menganalisa
Masalah menghapus file sementara sangat sederhana. Anda hanya perlu memanggil metode delete () FileItem setelah semua operasi selesai.
Untuk mencegah file yang diunggah dari dikelola oleh server web, kami dapat menempatkan lokasi file yang diunggah di Web-INF/ direktori!
Untuk nama file yang sama, kami dapat menggunakan nama file UUID+ yang diunggah oleh pengguna sebagai nama file simpan kami yang diunggah. Nama file seperti itu unik.
Untuk memecah file yang diunggah, kita perlu menggunakan algoritma HashCode untuk putus.
Empat bit yang lebih rendah menghasilkan direktori tingkat pertama 5-8 bit menghasilkan kode direktori tingkat kedua
Mari kita tulis kode file unggahan yang relatif lengkap
Gunakan algoritma HashCode untuk memecah direktori yang disimpan
Private String makeDirpath (string fileName, string path) {// Hitung direktori primer dan sekunder melalui nama file int hashCode = filename.hashcode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; String dir = path + "//" + dir1 + "//" + dir2; // Jika direktori tidak ada, buat file direktori file = file baru (dir); if (! file.exists ()) {file.mkdirs (); } // return The Full Path Return Dir; }Menghasilkan nama file yang unik
Private String makefileName (string fileName) {// Gunakan underscore untuk memisahkan uuid dan nama file, dan nama file dapat diuraikan nanti. return uuid.randomuuid (). tostring () + "_" + nama file; }Kode yang diunggah
// Buat pabrik diskfileitemFactory = DiskfileItemFactory baru (); // Buat parser melalui pabrik servletfileupload fileupload = servletfileupload baru (pabrik); // Atur kode unggahan fileupload.setHeaderencoding ("UTF-8"); // menilai jenis formulir unggahan jika (! Fileupload.ismultipartContent (permintaan)) {// Unggah formulir sebagai formulir normal, lalu dapatkan data dengan cara tradisional untuk kembali; } coba {// Parse objek permintaan untuk mendapatkan daftar [Muat semua konten yang diunggah] Daftar <FILEItEM> Daftar = FileUpload.ParSerequest (permintaan); // bepergian melalui daftar untuk menentukan apakah konten yang dimuat adalah bidang normal atau file unggah untuk (fileitem fileItem: list) {// Jika itu adalah item input normal jika (fileitem.isformField ()) {// dapatkan nama dan nilai item input name string = fileitem.getFieldName (); String value = FileItem.getString ("UTF-8"); System.out.println (name + "=" + value); } else {// Jika itu adalah file unggahan // dapatkan nama unggah [termasuk nama path] string filename = fileitem.getName (); // mencegat nama file fileName = filename.substring (filename.LastIndexof ("//") + 1); // menghasilkan nama file nama unik = makefilename (nama file); InputStream inputStream = fileitem.getInputStream (); // Dapatkan jalur proyek dan tulis file yang diunggah ke jalur string proyek = this.getSerVletContext (). GetRealPath ("/web-inf/unggahfile"); // Dapatkan string jalur direktori yang tersebar realpath = makedirpath (nama file, path); FileOutputStream outputStream = FileOutputStream baru (RealPath + "//" + FileName); byte [] bytes = byte baru [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {outputStream.write (bytes, 0, len); } inputStream.close (); outputStream.close (); // hapus data file sementara fileitem.delete (); }}} catch (fileuploadException e) {e.printstacktrace (); }Efek: Direktori berhasil dipecah, dan nama file itu unik.
Daftar file di direktori yang diunggah dan berikan unduhan
Saat menjelaskan objek respose, unduhan file telah dijelaskan. Kali ini kami akan menulis kasus kecil untuk mengkonsolidasikan unduhan file.
Ada 3 file di direktori unggahan
menganalisa
Pertama, daftar semua file di direktori. Karena kami perlu mengunduh file sesuai dengan nama file nanti, kami menggunakan koleksi peta untuk menyimpan semua file
Bagian pengunduhan juga sangat sederhana. Temukan file yang sesuai sesuai dengan nama file dan unggah lokasi file, baca dan tulis, lalu ubah header pesan untuk mencapai pengunduhan.
Dapatkan jalur untuk memuat dan mengunggah file, cari tahu semua file secara rekursif (menilai apakah itu file atau merupakan jalan keluar rekursif), memuatnya ke dalam koleksi peta dan meneruskan koleksi peta ke meja depan untuk ditampilkan ketika pengguna mengklik untuk diunduh, dan kemudian mendapatkan jalur absolut sesuai dengan nama asli. Jika sumber daya ada, pengguna diizinkan untuk mengunduh kode dan meletakkan semua file yang disimpan di Web-INF/ direktori di koleksi peta.
Dopost void yang dilindungi (permintaan httpservletRequest, respons httpservletResponse) melempar servletException, ioException {// Dapatkan direktori di mana file yang diunggah adalah string filepath = this.getServletContext (). getRealPath ("/web-inf/unggahan"); Peta peta = hashmap baru (); // Gunakan rekursi untuk mendapatkan semua file dan menambahkannya ke koleksi peta getAllFiles (file baru (filepath), peta); request.setAttribute ("peta", peta); request.getRequestDispatcher ("/listFile.jsp"). Forward (Request, Response); } private void getAllFiles (File FilePath, peta peta) {// Jika itu bukan file, maka itu adalah folder jika (! filepath.isfile ()) {// Cantumkan semua file di folder (mungkin file, mungkin file folder) [] file = filepath.listFiles (); untuk (file file: file) {// menilai file yang diperoleh (atau folder) dan getAllFiles (file, peta); }} else {// Masukkan pernyataan yang lain, itu harus file // dapatkan nama file string filename = filepath.getName (). substring (filePath.getName (). lastIndexof ("_") + 1); // Kami menyimpan nama lengkap file sebagai kunci dan nama file sebagai nilai di peta koleksi peta.put (filePath.getName (), fileName); }}Tampilkan file yang dapat diunduh di halaman JSP
<c: foreach item = "$ {peta}" var = "me"> <c: url var = "url" value = "/downfileServlet"> <c: param name = "filename" value = "$ {me.key}"> </c: param> </c: url> $ {me.value} </c: param> </c: url> $ {me.value} <a href = "{a href =" $ {URL "$ {Me.value} </ikut over: a href =" $ {{a href = "$" </a> <br> </c: foreach>Menerapkan servlet yang diunduh
Dopost void yang dilindungi (permintaan httpservletRequest, respons httpservletResponse) melempar servletException, ioException {// dapatkan nama lengkap file string fileNeName = request.getParameter ("fileName"); // Jika itu adalah data Cina, transcoding diperlukan. filename = string baru (filename.getbytes ("iso8859-1"), "UTF-8"); // Dapatkan lokasi di mana file disimpan string path = this.getSerVletContext (). GetRealPath ("/Web-inf/unggahfile"); // File disimpan melalui nama file dengan kode hashCode, dan file diperoleh melalui nama file string filerealpath = makefilePath (fileName, path); System.out.println (FileReAlPath); // menilai apakah file ada file = file baru (filerealpath); if (! File.exists ()) {request.setAttribute ("pesan", "sumber daya yang ingin Anda unduh tidak ada!"); request.getRequestDispatcher ("/message.jsp"). Forward (Request, Response); kembali ; } // ada // Baca file dan tulis data ke browser FileInputStream inputStream = new FileInputStream (FileReAlPath); byte [] bytes = byte baru [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {response.getOutputStream (). write (bytes, 0, len); } inputStream.close (); // Atur header pesan untuk memberi tahu browser bahwa ini adalah nama string file yang diunduh = filename.substring (fileName.LastIndexof ("_") + 1); response.setHeader ("konten-disposisi", "lampiran; fileName =" + urlencoder.encode (nama, "UTF-8"))); } private string makefilePath (string fileName, string path) {int hashCode = filename.hashCode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; String dir = path + "//" + dir1 + "//" + dir2 + "//" + nama file; mengembalikan dir; }Memengaruhi
Jika ada kesalahan dalam artikel ini, harap perbaiki saya dan semua orang akan berkomunikasi satu sama lain. Terima kasih atas dukungan Anda ke wulin.com.