1. Tinjauan Upload File
Untuk mewujudkan fungsi unggahan file dalam pengembangan web, dua langkah diperlukan:
1. Tambahkan unggah item input ke halaman web
<Form Action = "#" Method = "POST" ENCTYPE = "Multipart/Form-Data"> <input type = "file" name = "filename1"/> <br> <input type = "file" name = "filename2"/> <br> <input type = "kirimkan" value = "unggah"/> <bentuk> <!-1. Form. Setelah menetapkan nilai ini, ketika browser mengunggah file, itu akan melampirkan data file ke badan pesan permintaan HTTP, dan menggunakan protokol MIME untuk menggambarkan file yang diunggah untuk memfasilitasi penerima untuk menguraikan dan memproses data yang diunggah. 3. Atribut nama input harus diatur, jika tidak browser tidak akan mengirim data file yang diunggah. ->
2. Baca data unggah file di servlet dan simpan ke hard disk server
Objek permintaan menyediakan metode GetInputStream, yang melaluinya data yang dikirimkan oleh klien dapat dibaca. Namun, karena pengguna dapat mengunggah banyak file secara bersamaan, itu adalah tugas yang sangat merepotkan untuk memprogram dan langsung membaca data yang diunggah di sisi servlet dan menguraikan data file yang sesuai secara terpisah.
Misalnya, berikut ini adalah beberapa isi protokol HTTP dari permintaan yang dikirim oleh browser yang dicegat saat mengunggah file:
Penerimaan-bahasa: ZH-hans-CN, ZH-HANS; Q = 0,5 Konten-Jenis: multipart/form-data; Boundary = --------------------------- 7DFA01D1908A4UA-CPU: AMD64Accept-encoding: GZIP, DeflateUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; Trident/7.0; RV: 11.0) seperti GECKOCONTENT: PANJANG-LAGU: 84; 65; 65; 85; 8.0; RV: 11.0) seperti GECKOCON: X64; 84; 85; RV: 11.0) seperti GECKONCON: 84; 84; 84; 84; RV: RV: 11.0) seperti Geckocontent: 84; Keep-AlivePragma: no-Cachecookie: jSessionId = 11CefF8E271AB62CE676B5A87B746B5F ----------------------------- 7DFA01D1908A4Content-Disposisi: Form-Data; name = "nama pengguna" Zhangsan ----------------------------- 7DFA01D1908A4CONTENT-DISPOSISI: Formulir-Data; name = "UserPass" 1234 ----------------------------- 7DFA01D1908A4Content-Disposisi: Formulir-Data; name = "FileName1"; FileName = "c: /users/asus/desktop/upload.txt"-Type: Teks/PlainThis adalah konten file pertama! ------------------------- 7DFA01D1908A4Content-Disposisi: Formulir-Data; name = "FileName1"; FileName = "c: /users/asus/desktop/upload2.txt"-Type: Teks/PlainThis adalah konten file kedua! Halo ------------------------- 7DFA01D1908A4--
Ini juga dapat dilihat dari data di atas bahwa sulit untuk menulis program yang kuat dan stabil jika Anda membagi secara manual dan membaca data. Oleh karena itu, untuk memfasilitasi pengguna untuk memproses data unggahan, Organisasi Sumber Terbuka Apache menyediakan komponen open source (Commons-Fileupload) yang digunakan untuk memproses pengunggahan file formulir. Komponen ini memiliki kinerja yang sangat baik dan API -nya sangat mudah digunakan, yang memungkinkan pengembang untuk dengan mudah mengimplementasikan fungsi unggahan file web. Oleh karena itu, dalam pengembangan web, fungsi unggahan file biasanya diimplementasikan menggunakan komponen Commons-Fileupload.
Dua paket stoples perlu diimpor: Commons-Fileupload, Commons -o
response.setContentType ("Text/html; charset = UTF-8"); // Tetapkan permintaan pengkodean respons.setcharacterencoding ("UTF-8"); PrintWriter writer = response.getWriter();//Get response output stream ServletInputStream inputStream = request.getInputStream();//Get request input stream/* * 1. Create a DiskFileItemFactory object, set the buffer size and temporary file directory* There are two constructors in this class, one is a constructor without parameters, and the other is a constructor with two parameters* @param int Sizethreshold, parameter ini menetapkan ukuran buffer memori, nilai default adalah 10k. Ketika file unggahan lebih besar dari ukuran buffer, komponen fileupload akan mengunggah file menggunakan cache file sementara* @param java.io.file repositori, parameter ini menentukan direktori file sementara, nilai default adalah system.getProperty ("java.io.tmpdir"); * * Jika konstruktor tanpa parameter digunakan, setsizeThreshold (int sizethreshold), setRepository (java.io.file repositori) * Metode diatur secara manual */ DiskfileItemFactory factory = New DiskfileItemFactory (); int sizethreshold = 1024*1024; factory.setsizeThreshold (sizethreshold); File repository = file baru (request.getSession (). GetserVletContext (). GetRealPath ("temp")); // system.out.println (request.getSession (). GetServletContext (). GetRealpath ("temp")); // system.out.println (request.getReal ("Temp")); // System.out.println (getRealpath ("Temp"));/ System.out.println (getRealpath ("Temp")); factory.setrepository (repositori); /* * 2. Use the DiskFileItemFactory object to create a ServletFileUpload object and set the size of the uploaded file* * The ServletFileUpload object is responsible for processing the uploaded file data and encapsulate each input item in the form into a FileItem * Common methods of this object are: * boolean isMultipartContent(request); Tentukan apakah formulir yang diunggah adalah Multipart/Form-Data Type* Daftar Parserequest (permintaan); Parse objek permintaan, bungkus setiap item input dalam formulir ke dalam objek FileItem, dan kembalikan koleksi daftar yang menyimpan semua fileitem* void setFileSizeMax (long filesizeMax); Atur nilai maksimum satu file yang diunggah* batal setSizeMax (Long Sizemax); Tetapkan nilai maksimum dari jumlah total wenjiang* void setheaderencoding () yang diunggah; Atur format pengkodean untuk menyelesaikan masalah nama file yang mengunggah kode kacau*/ servletfileupload unggah = servletfileupload baru (pabrik); unggah. coba {parserequest = unggah.parserequest (permintaan); } catch (FileuploAdException e) {E.PrintStackTrace (); } / * * 4. Iterasi melalui daftar. Setiap mengulangi objek FileItem, panggil metode ISFormField -nya untuk menentukan apakah itu adalah unggahan file* Benar berarti itu adalah bidang formulir yang normal, lalu panggil GetFieldName dan GetTring Metode untuk mendapatkan nama bidang dan nilai bidang* Salah adalah file unggahan, dan kemudian memanggil file unggahan yang digunakan secara umum atau file unggahan yang digunakan sebagai sebuah file unggahan yang digunakan* Fileitem yang digunakan untuk menggunakan sebuah file unggahan** yang digunakan file. Metode objek ini adalah: * boolean isFormField (); Menentukan apakah FileItem adalah objek unggahan file atau objek formulir normal * Benar berarti itu adalah bidang formulir yang normal, * Kemudian hubungi GetFieldName dan GetTring Metode untuk mendapatkan nama bidang dan nilai bidang * Salah sebagai file unggahan, * lalu hubungi getName () untuk mendapatkan nama file dari file unggah. Catatan: Beberapa browser membawa jalur klien dan perlu mengurangi diri sendiri * Call getInputStream () metode untuk mendapatkan aliran input data, sehingga dapat membaca data unggahan * hapus (); berarti bahwa setelah menutup aliran input FileItem, hapus file sementara dihapus. */for (FileItem FileItem: ParSeRequest) {if (fileitem.isFormField ()) {// mewakili bidang normal jika ("nama pengguna" .sequals (fileitem.getFieldName ()))) {string username = fileitem.getString (); writer.write ("Nama Pengguna Anda:"+Nama Pengguna+"<br>"); } if ("userpass" .equals (fileitem.getFieldName ())) {string userpass = fileitem.getString (); writer.write ("Kata Sandi Anda:"+UserPass+"<br>"); }} else {// berarti file yang diunggah // String filename = ""; if (clientName.contains ("//")) {// if "/" berarti nama dengan path, nama file terakhir dicegat fileName = clientName.substring (clientName.LastIndexof ("//"). Substring (1); } else {filename = clientName; } Uuid randomuuid = uuid.randomuuid (); // menghasilkan 128-bit panjang file pengidentifikasi unik secara global = acakuuid.tostring ()+nama file; / * * Desain algoritma generasi direktori. Jika jumlah total file yang diunggah oleh pengguna adalah pesanan jutaan pesanan besar atau lebih, menempatkannya di direktori yang sama menyebabkan indeks file menjadi sangat lambat. * Oleh karena itu, sangat penting untuk merancang struktur direktori untuk menyimpan file dengan cara yang tersebar, dan secara wajar * mengubah algoritma hash uuid menjadi kisaran yang lebih kecil, * mengubah kode hash dari uuid menjadi direktori 8-bit di masing-masing level ini, setiap direksi di bawah level ini, masing-masing level di bawah level ini, masing-masing level di bawah level, masing-masing level di bawah level ini, masing-masing level di bawah level, masing-masing adalah 16-level level, masing-masing adalah 16-level level, masing-masing direkori di bawah l adalah struktur direktori yang efisien untuk server dan sistem operasi*/ int hashuuid = randomuuid.hashcode (); String hexuuid = integer.tohexstring (hashuuid); //System.out.println(Hexuuid); // Dapatkan jalur absolut ke folder mana yang akan menyimpan file yang diunggah di string filePath = request.getSession (). GetserVletContext (). GetRealPath ("unggah"); untuk (char c: hexuuid.tochararray ()) {filepath = filepath+"/"+c; } // Jika direktori tidak ada, hasilkan file direktori tingkat delapan filepathFile = file baru (filepath); if (! filePathFile.exists ()) {filepathfile.mkdirs (); } // Baca file dari aliran input permintaan dan tulis ke server inputStream inputStream2 = fileitem.getInputStream (); // Buat file di file sisi server file = file baru (filepath+"/"+fileName); BufferedOutputStream bos = baru bufferedoutputStream (fileoutputStream baru (file)); byte [] buffer = byte baru [10*1024]; int len = 0; while ((len = inputStream2.read (buffer, 0, 10*1024))! =-1) {bos.write (buffer, 0, len); } writer.write ("Anda mengunggah file"+clientName+"berhasil <br>"); // tutup sumber daya bos.close (); inputStream2.close (); }} // Perhatikan bahwa file Eclipse yang diunggah disimpan di direktori menjalankan proyek, bukan di direktori proyek di ruang kerja.2. Masalah yang membutuhkan perhatian khusus untuk mengunggah file: (Masalah ini semuanya disediakan dengan solusi sederhana dalam kode di atas)
1. Di mana menyimpan file
Untuk memastikan keamanan server, file yang diunggah harus disimpan dalam direktori web-INF aplikasi, atau direktori yang tidak dikelola oleh server web. Jika pengguna mengunggah file dengan kode yang dapat dieksekusi, seperti file JSP, dan mengaksesnya sesuai dengan jalur akses splicing, ia dapat melakukan apa saja di sisi server.
2. Untuk mencegah beberapa pengguna mengunggah file dengan nama file yang sama, menghasilkan file yang menimpa, pengunggah file harus memastikan bahwa file yang diunggah memiliki nama file yang unik .
Ganti nama menggunakan nama file UUID + USER
Tentang uuid:
UUID (pengidentifikasi unik secara universal) pengidentifikasi unik secara global mengacu pada angka yang dihasilkan pada mesin, yang memastikan bahwa itu unik untuk semua mesin dalam waktu dan ruang yang sama. Menurut standar yang ditetapkan oleh Open Software Foundation (OSF), alamat kartu Ethernet, waktu nanosecond, kode ID chip dan banyak angka yang mungkin digunakan. Ini terdiri dari kombinasi bagian -bagian berikut: Tanggal dan waktu saat ini (bagian pertama dari UUID terkait dengan waktu. Jika Anda menghasilkan UUID lain beberapa detik setelah menghasilkan UUID, bagian pertama berbeda, sisanya sama), tidak ada jalan, dan network yang diperoleh di jaringan IEEE yang diperoleh secara global (jika ada kartu jaringan, itu diperoleh dari uU, dan tidak ada kartu identifikasi Network (jika tidak ada jaringan, dan tidak ada kartu yang diperoleh dari jaringan, dan tidak ada. adalah bahwa string hasil yang dihasilkan akan relatif panjang.
Ini adalah angka panjang 128-bit, umumnya diekspresikan dalam heksadesimal. Gagasan inti dari algoritma ini adalah untuk menghasilkan guid dalam kombinasi dengan kartu jaringan mesin, waktu setempat, dan nomor instan. Secara teoritis, jika sebuah mesin menghasilkan 100.000 guid per detik, dapat dijamin (dalam arti probabilitas) bahwa 3240 tahun tidak akan diulang.
Mulai dari JDK1.5, menghasilkan UUIDS telah menjadi hal yang sederhana, berpikir bahwa JDK telah menerapkan UUIDS:
java.util.uuid, sebut saja secara langsung.
Uuid uuid = uuid.randomuuid ();
String s = uuid.randomuuid (). ToString (); // ID kunci utama yang digunakan untuk menghasilkan database sangat bagus. .
UUID terdiri dari nomor enam belas digit, yang dinyatakan dalam bentuk
550E8400-E29B-11D4-A716-446655440000
3. Untuk mencegah terlalu banyak file dalam satu direktori dan mempengaruhi kecepatan membaca file dan penulisan, program yang menangani file mengunggah harus memilih algoritma pembuatan struktur direktori yang sesuai berdasarkan total volume unggahan yang mungkin, dan menyimpan file yang diunggah dengan cara yang tersebar. Misalnya, gunakan metode HashCode untuk membangun direktori multi-level.
4. Jika pengguna yang berbeda mengunggah file yang sama, tidak perlu menyimpan banyak salinan file yang sama di sisi server. Ini adalah pemborosan sumber daya. Suatu algoritma harus dirancang untuk menyelesaikan masalah file duplikat.
5. Prinsip teknologi JSP secara otomatis mengimplementasikan multi-threading. Oleh karena itu, pengembang tidak perlu mempertimbangkan operasi multi-threaded dalam mengunggah file
3. Unduh File
<% Arraylist <string> fileNames = new ArrayList <string> (); filenames.add ("file/aa.txt"); filenames.add ("file/bb.jpg"); untuk (string filename: fileNames) { %> <form Action = "downloadservlet" Method = "get"> <input type = "hidden" name = "filename" value = "< %= fileName %>" /> <input type = "kirim" value = "unduh: < %filename % %> / /< /form> < %}; String filename = request.getParameter ("fileName"); String urlname = urlencoder.encode (nama file, "UTF-8"); // Cegah respons Cina yang kacau. FileInputStream fis = new fileInputStream (file baru (request.getSession (). GetserVletContext (). GetRealPath (fileName))); BufferedInputStream bis = baru bufferedInputStream (FIS); ServETOutputStream sos = response.getoutputStream (); byte [] buffer = byte baru [1024]; int len = 0; while ((len = bis.read (buffer, 0, 1024))! =-1) {sos.write (buffer, 0, len); } bis.close (); fis.close ();4. Gunakan komponen Smartupload di SSH untuk menyederhanakan unggahan file dan unduh
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.