Unggah file sangat umum dalam aplikasi web. Sangat mudah untuk mengimplementasikan fungsi pengunggahan file di lingkungan JSP, karena ada banyak komponen unggahan file yang dikembangkan di Java di Internet. Artikel ini mengambil komponen Commons-Fileupload sebagai contoh untuk menambahkan fungsi unggahan file ke aplikasi JSP.
Komponen Common-Fileupload adalah salah satu proyek open source Apache dan dapat diunduh dari http://jakarta.apache.org/commons/fileupload/.
Komponen ini memungkinkan Anda untuk mengunggah satu atau lebih file sekaligus dan dapat membatasi ukuran file.
Setelah mengunduh, unzip paket zip dan salin commons-fileupload-1.0.jar ke webapps Tomcat di bawah webappweb-inflib Anda. Jika direktori tidak ada, silakan buat direktori Anda sendiri.
Buat servlet baru: unggah.java untuk unggahan file:
impor java.io.*; impor java.util.*; impor javax.servlet.*; impor javax.servlet.http.*; impor org.apache.commons.fileupload.*; unggahan kelas publik memperluas httpservlet {private string unggahPath = "c: unggah"; // direktori untuk mengunggah file pribadi string temppath = "c: unggahtmp"; // Direktori File Sementara Void Dopost (permintaan httpservletrequest, respons httpservletResponse) melempar ioException, servletException {}}Dalam metode dopost (), ketika servlet menerima permintaan pos yang dikeluarkan oleh browser, ia menyadari unggahan file. Ini kode sampelnya:
public void dopost (permintaan httpservletRequest, respons httpservletResponse) melempar ioException, servletException {coba {diskfileupload fu = new diskfileUpload (); // Atur ukuran file maksimum, di sini adalah 4MBFU.SetsizeMax (4194304); // Atur ukuran buffer, di sini adalah 4KBFU.SetsizeThreshold (4096); // Atur direktori sementara: fu.setrepositorypath (Temppath); // Dapatkan semua file: daftar fileItems = fu.parsequest (permintaan); Iterator i = fileitems.iterator (); // Proses setiap file dalam urutan: while (i.hasnext ()) {fileItem fi = (fileItem) i.next (); // Dapatkan nama file, nama file termasuk path: string filename = fi.getName (); // Di sini Anda dapat merekam informasi pengguna dan file // ... // tulis ke file, nama file tentatif adalah A.TXT, dan nama file dapat diekstraksi dari nama file: fi.write (file baru (unggahPath + "a.txt")); }} catch (Exception e) {// Anda dapat melompat ke halaman kesalahan}}Jika Anda ingin membaca folder unggahan yang ditentukan di file konfigurasi, Anda dapat menjalankannya di metode init ():
public void init () melempar servletException {unggahpath = .... Temppath = .... // Jika folder tidak ada, itu akan dibuat secara otomatis: jika (! File baru (unggahpath) .isdirectory ()) file baru (unggahpath) .mkdirs (); if (! File baru (Temppath) .isDirectory ()) File baru (Temppath) .mkdirs (); }Kompilasi servlet, berhati-hatilah untuk menentukan classpath, pastikan untuk menyertakan commons-upload-1.0.jar dan tomcatcommonlibservlet-api.jar.
Konfigurasikan servlet, gunakan notepad untuk membuka tomcatwebapps untuk webappweb-infweb.xml Anda, dan buat yang baru jika tidak.
Konfigurasi khas adalah sebagai berikut:
〈? XML Versi = "1.0" encoding = "iso-8859-1"? Antikan 〈! Doctype Web-Apppublic "-// Sun Microsystems, Inc.//DTD Aplikasi Web 2.3 // en "" http://java.sun.com/dtd/web-app_2_3.dtd "> 〈web-app> 〈servlet> 〈servlet-name> unggah 〈/servlet-name> 〈servlet-class> unggah 〈/s Ervlet-Class> 〈Servlet 〈servlet-name> Unggah 〈/servlet-name> 〈url-pola /fileupload 〈/URL-pola 〈/servlet 〈/web-app 〈
Setelah mengkonfigurasi servlet, mulailah Tomcat dan tulis tes HTML sederhana:
〈Form Action = "FileUpload" Method = "POST" ENCTYPE = "multipart/form-data" name = "Form1"> 〈input type = "file" name = "file"> 〈input type = "kirim" name = "kirim" value = "unggah"> 〈/bentuk>
Catatan Action = "FileUpload" di mana fileupload adalah pola URL yang ditentukan saat mengkonfigurasi servlet.
Ini kode untuk udang:
Unggah ini jauh lebih mudah digunakan daripada Smartupload. Itu benar -benar dibuat oleh saya byte satu per satu, tidak seperti Smartupload yang memiliki banyak bug.
Metode Panggilan:
Unggah up = unggah baru (); up.init (permintaan); /** Dapat menelepon setsavedir (string savedir); Atur jalur simpan dan hubungi setmaxfileSize (ukuran panjang) untuk mengatur byte maksimum file yang diunggah. Hubungi SettagFileName (String) untuk mengatur nama file setelah diunggah (hanya valid untuk file pertama)*/up. unggahfile ();
Kemudian string [] name = up.getFileName (); Dapatkan nama file yang diunggah, jalur absolut dari file tersebut seharusnya
Simpan Direktori Savedir+"/"+Nama [i];
Anda bisa mendapatkan teks yang diunggah atau Up.getParametervalues ("diajukan") melalui up.getParameter ("bidang");
Dapatkan nilai bidang dengan nama yang sama seperti beberapa kotak centang.
Cobalah yang lain sendiri.
Kode sumber adalah sebagai berikut: ______________________________________________________________________
paket com.inmsg.beans; impor java.io.*; impor java.util.*; impor javax.servlet.*; impor javax.servlet.http.*; unggah kelas publik {private string savedir = "."; // path untuk menyimpan file private string contentType = ""; // Jenis dokumen Private String charset = ""; // Karakter Set Private ArrayList tmpFileName = new arraylist (); // Struktur Data Sementara untuk Menyimpan Nama File Parameter Hashtable Pribadi = Hashtable Baru (); // Struktur Data yang Menyimpan Nama dan Nilai Parameter Konteks ServletContext Pribadi; // Konteks program, digunakan untuk menginisialisasi permintaan httpservletRequest pribadi; // instance yang digunakan untuk meneruskan objek permintaan private string boundary = ""; // memori data pemisah pribadi int len = 0; // Panjang byte sebenarnya dibaca dari bagian dalam setiap kali string private QueryString; Hitungan int pribadi; // Jumlah total file yang diunggah Private String [] fileName; // diunggah nama file array pribadi long maxfileSize = 1024 * 1024 * 10; // byte unggahan file maksimum; private string tagfileName = ""; public final void init (permintaan httpservletRequest) melempar servletException {this.Request = request; batas = request.getContentType (). Substring (30); // Dapatkan queryString pembatas data dalam memori = request.getQueryString (); } public String getParameter (String s) {// Digunakan untuk mendapatkan nilai parameter dari bidang yang ditentukan, override request.getParameter (string s) if (parameter.isempty ()) {return null; } return (string) parameter.get (s); } public String [] getParameterValues (String s) {// Digunakan untuk mendapatkan array parameter yang ditentukan dengan bidang nama yang sama, override request.getParameterS (string s) arraylist al = new arraylist (); if (parameter.isempty ()) {return null; } Enumeration e = parameter.keys (); while (e.hasmoreElements ()) {string key = (string) e.nextElement (); if (-1! = key.indexof (s + "||||||||||||") || key.equals (s)) {al.add (parameter.get (key)); }} if (al.size () == 0) {return null; } String [] value = string baru [al.size ()]; untuk (int i = 0; i 〈value.length; i ++) {value [i] = (string) al.get (i); } nilai pengembalian; } public String getQueryString () {return queryString; } public int getCount () {return count; } public string [] getFileName () {return fileName; } public void setmaxFileSize (ukuran panjang) {maxFileSize = size; } public void settagFileName (string fileName) {tagFileName = fileName; } public void setSaveDir (String saveDir) {// Setel path untuk menyimpan untuk mengunggah file this.saveDir = saveDir; File testdir = file baru (saveDir); // Untuk memastikan bahwa direktori ada, jika tidak ada, buat direktori jika (! Testdir.exists ()) {testdir.mkdir (); }} public void setCharset (string charset) {// Atur karakter set ini.charset = charset; } public boolean unggahfile () melempar servletException, ioException {// unggah metode yang dipanggil oleh pengguna setCharset (request.getcharacterencoding ()); return unggah (request.getInputStream ()); } private boolean unggah (servletInputStream servletInputStream) lemparan // metode utama untuk mendapatkan data penyimpanan pusat servletException, ioException {string line = null; byte [] buffer = byte baru [256]; while ((line = readline (buffer, servletInputStream, charset))! = null) {if (line.startswith ("Disposisi konten: form-data;"))) {int i = line.indexof ("filename ="); if (i = 0) {// Jika ada fileName = dalam deskripsi dalam pembatas, itu berarti bahwa itu adalah konten yang dikodekan dari string file fname = getFileName (baris); if (fname.equals ("")) {lanjutan; } if (count == 0 && tagfileName.length ()! = 0) {string ext = fname.substring ((fname.LastIndexof (".") + 1)); fname = tagfileName + "." + ext; } tmpfileName.add (fname); Count ++; while ((line = readline (buffer, servletInputStream, charset))! = null) {if (line.length () 〈= 2) {break; }} File f = file baru (saveDir, fname); FileOutputStream dos = new FileOutputStream (f); Ukuran Panjang = 0L; while ((line = readline (buffer, servletInputStream, null))! = null) {if (line.indexof (batas)! = -1) {break; } ukuran += len; if (size maxfileSize) {lempar ioException baru ("file melebihi" + maxfileSize + "byte!"); } dos.write (buffer, 0, len); } dos.close (); } else {// Kalau tidak, itu adalah konten dari bidang pengkodean string key = getKey (line); Nilai string = ""; while ((line = readline (buffer, servletInputStream, charset))! = null) {if (line.length () 〈= 2) {break; }} while ((line = readline (buffer, servletInputStream, charset))! = null) {if (line.indexof (batas)! = -1) {break; } value += line; } put (tombol, value.trim (), parameter); }}} if (queryString! = null) {string [] masing -masing = split (queryString, "&"); untuk (int k = 0; k 〈masing -masing.length; k ++) {string [] nv = split (masing -masing [k], "="); if (nv.length == 2) {put (nv [0], nv [1], parameter); }}} fileName = string baru [tmpFileName.size ()]; untuk (int k = 0; k 〈fileName.length; k ++) {fileName [k] = (string) tmpFileName.get (k); // tuang nama file sementara di arraylist ke dalam data untuk pengguna untuk menelepon} if (filename.length == 0) {return false; // Jika data nama file kosong, itu berarti tidak ada file yang diunggah} return true; } private void put (tombol string, nilai string, hashtable ht) {if (! ht.containskey (key)) {ht.put (key, value); } else {// Jika Anda sudah memiliki kunci dengan nama yang sama, Anda harus mengganti nama kunci saat ini. Pada saat yang sama, berhati -hatilah untuk tidak membentuk nama yang sama dengan kunci coba {thread.currentThread (). Sleep (1); // Agar tidak menghasilkan dua tombol identik dalam tangkapan ms} yang sama (pengecualian e) {} tombol += "|||||||||||" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" + System.currentTimemillis (); ht.put (tombol, nilai); }}/* Panggilan servletInputStream.readline (byte [] b, int offset, length) metode, yang membaca baris dari aliran servletInputStream ke array byte yang ditentukan. Untuk memastikan bahwa itu dapat mengakomodasi suatu garis, byte [] B tidak boleh kurang dari 256. Dalam readline yang ditulis ulang, variabel anggota Len dipanggil ke jumlah byte yang sebenarnya dibaca (beberapa baris kurang dari 256). Saat menulis konten file, byte dari panjang Len harus ditulis dari array byte, bukan seluruh panjang byte []. Namun, metode yang ditulis ulang mengembalikan string untuk menganalisis konten yang sebenarnya dan tidak dapat mengembalikan Len, sehingga Len ditetapkan sebagai variabel anggota dan menetapkan panjang aktual untuk itu setiap kali operasi baca. Dengan kata lain, ketika memproses konten file, data harus dikembalikan dalam bentuk string untuk menganalisis tanda awal dan akhir, dan juga ditulis ke aliran output file dalam bentuk byte [] pada saat yang sama. */Private String Readline (byte [] linebyte, servletInputStream servletInputStream, string charset) {coba {len = servletInputStream.readline (linebyte, 0, linebyte.length); if (len == -1) {return null; } if (charset == null) {return new string (linebyte, 0, len); } else {return string baru (linebyte, 0, len, charset); }} catch (Exception _ex) {return null; }} private string getFileName (string line) {// Pisahkan nama file dari string deskripsi if (line == null) {return ""; } int i = line.indexOf ("FileName ="); line = line.substring (i + 9) .trim (); i = line.LastIndexOf (""); if (i 〈0 || i = line.length () - 1) {i = line.LastIndexof ("/"); if (line.equals ("" "")) {return ""; } if (i 〈0 || i = line.length () - 1) {return line; }} return line.substring (i + 1, line.length () - 1); } private string getKey (string line) {// pisahkan nama bidang dari string deskripsi if (line == null) {return ""; } int i = line.indexof ("name ="); line = line.substring (i + 5) .trim (); return line.substring (1, line.length () - 1); } public static string [] split (string strob, string mark) {if (strob == null) {return null; } StringTokenizer st = new stringTokenizer (strob, mark); ArrayList TMP = ArrayList baru (); while (st.hasmoretokens ()) {tmp.add (St.NextToken ()); } String [] strarr = string baru [tmp.size ()]; untuk (int i = 0; i 〈tmp.size (); i ++) {strarr [i] = (string) tmp.get (i); } return strarr; }} Unduh sebenarnya sangat sederhana. Selama Anda memprosesnya sebagai berikut, tidak ada masalah yang akan terjadi. Unduh public void (String FilePath, HTTPServletResponse Response, Boolean ISOnline) melempar Exception {file f = file baru (FilePath); if (! f.exists ()) {response.senderror (404, "file tidak ditemukan!"); kembali; } BufferedInputStream br = new bufferedInputStream (FileInputStream baru (f)); byte [] buf = byte baru [1024]; int len = 0; response.reset (); // Sangat penting jika (isOnline) {// Ononopen Metode URL U = URL baru ("File: ///"+FilePath); response.setContentType (u.openconnection (). getContentType ()); response.setHeader ("Disposisi konten", "inline; fileName ="+f.getName ()); // Nama file harus dikodekan sebagai UTF-8} else {// Metode unduhan murni response.setContentType ("Application/x-msdownload"); response.setHeader ("Disposisi konten", "lampiran; fileName =" + f.getName ()); } OutputStream out = response.getoutputStream (); while ((len = br.read (buf)) antikan 0) out.write (buf, 0, len); br.close (); out.close (); }