Bagaimana saya bisa mengunggah file ke server menggunakan JSP / Servlet? Saya mencoba ini:
<form action="upload" method="post">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" />
</form>
Namun, saya hanya mendapatkan nama file, bukan konten file. Ketika saya menambahkan enctype="multipart/form-data"
ke <form>
, lalu request.getParameter()
kembali null
.
Selama penelitian saya menemukan Apache Common FileUpload . Saya mencoba ini:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.
Sayangnya, servlet melempar pengecualian tanpa pesan dan sebab yang jelas. Inilah stacktrace:
SEVERE: Servlet.service() for servlet UploadServlet threw exception
javax.servlet.ServletException: Servlet execution threw an exception
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:313)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:637)
java
jsp
jakarta-ee
servlets
file-upload
Thang Pham
sumber
sumber
Jawaban:
pengantar
Untuk menelusuri dan memilih file untuk diunggah, Anda perlu
<input type="file">
bidang HTML dalam formulir. Seperti yang dinyatakan dalam spesifikasi HTML Anda harus menggunakanPOST
metode danenctype
atribut formulir harus diatur"multipart/form-data"
.Setelah mengirimkan formulir seperti itu, data formulir multi-biner tersedia di badan permintaan dalam format yang berbeda dari ketika
enctype
tidak diatur.Sebelum Servlet 3.0, Servlet API tidak mendukung secara asli
multipart/form-data
. Ini hanya mendukung bentuk standar dariapplication/x-www-form-urlencoded
. Therequest.getParameter()
dan permaisuri akan semua kembalinull
bila menggunakan data formulir multi. Di sinilah FileUpload Apache Commons yang terkenal muncul.Jangan parsing secara manual!
Secara teori Anda dapat menguraikan tubuh permintaan sendiri berdasarkan
ServletRequest#getInputStream()
. Namun, ini adalah pekerjaan yang tepat dan membosankan yang membutuhkan pengetahuan yang akurat tentang RFC2388 . Anda tidak boleh mencoba melakukan ini sendiri atau menyalin beberapa kode pustaka buatan sendiri yang ditemukan di tempat lain di Internet. Banyak sumber online gagal dalam hal ini, seperti roseindia.net. Lihat juga mengunggah file pdf . Anda sebaiknya menggunakan perpustakaan asli yang digunakan (dan diuji secara implisit!) Oleh jutaan pengguna selama bertahun-tahun. Perpustakaan seperti itu telah membuktikan kekokohannya.Saat Anda sudah menggunakan Servlet 3.0 atau yang lebih baru, gunakan API asli
Jika Anda menggunakan setidaknya Servlet 3.0 (Tomcat 7, Jetty 9, JBoss AS 6, GlassFish 3, dll), maka Anda dapat menggunakan API standar yang disediakan
HttpServletRequest#getPart()
untuk mengumpulkan item data formulir multi-individu (kebanyakan implementasi Servlet 3.0 sebenarnya menggunakan Apache Commons FileUpload di bawah sampul untuk ini!). Juga, bidang formulir normal tersedia dengangetParameter()
cara biasa.Pertama,
@MultipartConfig
beri anotasi pada servlet Anda agar dapat mengenali dan mendukungmultipart/form-data
permintaan dan mulaigetPart()
bekerja:Kemudian, implementasikan
doPost()
sebagai berikut:Perhatikan
Path#getFileName()
. Ini adalah perbaikan MSIE untuk mendapatkan nama file. Browser ini salah mengirim jalur file lengkap di sepanjang nama, bukan hanya nama file.Jika Anda memiliki
<input type="file" name="file" multiple="true" />
unggahan multi-file, kumpulkan sebagai berikut (sayangnya tidak ada metode seperti iturequest.getParts("file")
):Saat Anda belum menggunakan Servlet 3.1, dapatkan nama file yang dikirimkan secara manual
Catatan yang
Part#getSubmittedFileName()
diperkenalkan di Servlet 3.1 (Tomcat 8, Jetty 9, WildFly 8, GlassFish 4, dll). Jika Anda belum menggunakan Servlet 3.1, maka Anda memerlukan metode utilitas tambahan untuk mendapatkan nama file yang dikirimkan.Perhatikan perbaikan MSIE untuk mendapatkan nama file. Browser ini salah mengirim jalur file lengkap di sepanjang nama, bukan hanya nama file.
Saat Anda belum menggunakan Servlet 3.0, gunakan Apache Commons FileUpload
Jika Anda belum menggunakan Servlet 3.0 (bukankah ini saatnya untuk memutakhirkan?), Praktik umum adalah menggunakan Apache Commons FileUpload untuk menguraikan permintaan data formulir multi-bagian. Ini memiliki Panduan Pengguna dan FAQ yang sangat baik (hati-hati melalui keduanya). Ada juga O'Reilly (" cos ")
MultipartRequest
, tetapi ia memiliki beberapa bug (minor) dan tidak aktif lagi selama bertahun-tahun. Saya tidak akan merekomendasikan menggunakannya. Apache Commons FileUpload masih dipelihara secara aktif dan saat ini sangat matang.Untuk menggunakan FileUpload Apache Commons, Anda harus memiliki setidaknya file berikut di aplikasi web Anda
/WEB-INF/lib
:commons-fileupload.jar
commons-io.jar
Upaya awal Anda kemungkinan besar gagal karena Anda lupa IO milik bersama.
Berikut ini contoh kickoff bagaimana tampilan
doPost()
AndaUploadServlet
saat menggunakan Apache Commons FileUpload:Ini sangat penting bahwa Anda tidak menelepon
getParameter()
,getParameterMap()
,getParameterValues()
,getInputStream()
,getReader()
, dll pada permintaan yang sama sebelumnya. Jika tidak, wadah servlet akan membaca dan mem-parsing badan permintaan dan dengan demikian Apache Commons FileUpload akan mendapatkan badan permintaan kosong. Lihat juga ao ServletFileUpload # parseRequest (request) mengembalikan daftar kosong .Perhatikan
FilenameUtils#getName()
. Ini adalah perbaikan MSIE untuk mendapatkan nama file. Browser ini salah mengirim jalur file lengkap di sepanjang nama, bukan hanya nama file.Atau Anda juga dapat membungkus semua ini dengan cara
Filter
mem-parsing semuanya secara otomatis dan memasukkan barang-barang itu kembali ke dalam parametermap permintaan sehingga Anda dapat terus menggunakanrequest.getParameter()
cara biasa dan mengambil file yang diunggahrequest.getAttribute()
. Anda dapat menemukan contoh di artikel blog ini .Solusi untuk bug GlassFish3
getParameter()
masih kembalinull
Perhatikan bahwa versi Glassfish yang lebih tua dari 3.1.2 memiliki bug di mana
getParameter()
masih kembalinull
. Jika Anda menargetkan wadah seperti itu dan tidak dapat memutakhirkannya, maka Anda perlu mengekstraksi nilainyagetPart()
dengan bantuan metode utilitas ini:Menyimpan file yang diunggah (jangan gunakan
getRealPath()
jugapart.write()
!)Buka jawaban berikut untuk perincian tentang cara menyimpan dengan benar yang diperoleh
InputStream
(fileContent
variabel seperti yang ditunjukkan dalam cuplikan kode di atas) ke disk atau basis data:Melayani file yang diunggah
Buka jawaban berikut untuk detail tentang penyajian file yang disimpan dengan benar dari disk atau database kembali ke klien:
Ajaxifying formulir
Buka jawaban berikut cara mengunggah menggunakan Ajax (dan jQuery). Perhatikan bahwa kode servlet untuk mengumpulkan data formulir tidak perlu diubah untuk ini! Hanya cara Anda merespons yang dapat diubah, tetapi ini agak sepele (yaitu alih-alih meneruskan ke JSP, cukup cetak beberapa JSON atau XML atau bahkan teks biasa tergantung pada apa pun yang diharapkan skrip yang bertanggung jawab atas panggilan Ajax).
Semoga ini semua membantu :)
sumber
request.getParts("file")
dan bingung x_xMultipartConfig
kondisi dilanggar (mismaxFileSize
.:), panggilanrequest.getParameter()
mengembalikan null. Apakah ini sengaja? Bagaimana jika saya mendapatkan beberapa parameter (teks) biasa sebelum memanggilgetPart
(dan memeriksaIllegalStateException
)? Ini menyebabkan sebuahNullPointerException
untuk dilempar sebelum saya memiliki kesempatan untuk memeriksaIllegalStateException
.String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
bagian yang mirip dengan sayaJika Anda menggunakan Spring MVC, ini adalah caranya: (Saya meninggalkan ini di sini kalau-kalau ada yang merasa berguna).
Gunakan formulir dengan
enctype
atribut yang disetel ke "multipart/form-data
" (Sama seperti BalusC's Answer)Di controller Anda, petakan parameter permintaan
file
untukMultipartFile
mengetik sebagai berikut:Anda bisa mendapatkan nama file dan ukuran menggunakan
MultipartFile
'sgetOriginalFilename()
dangetSize()
.Saya sudah menguji ini dengan versi Spring
4.1.1.RELEASE
.sumber
Anda perlu
common-io.1.4.jar
file untuk dimasukkan dalamlib
direktori Anda , atau jika Anda bekerja di editor apa pun, seperti NetBeans, maka Anda harus pergi ke properti proyek dan cukup tambahkan file JAR dan Anda akan selesai.Untuk mendapatkan
common.io.jar
file tersebut, cukup google saja atau buka situs web Apache Tomcat di mana Anda mendapatkan opsi untuk mengunduh file ini secara gratis. Tapi ingat satu hal: unduh file ZIP biner jika Anda pengguna Windows.sumber
.jar
tapi.zip
. Apakah yang Anda maksud.zip
?Tanpa komponen atau Perpustakaan eksternal di Tomcat 6 o 7
Mengaktifkan Unggahan dalam file web.xml :
http://joseluisbz.wordpress.com/2014/01/17/manually-installing-php-tomcat-and-httpd-lounge/#Enabling%20File%20Uploads .
YANG BISA ANDA LIHAT :
Mengunggah File menggunakan JSP. File:
Dalam file html
Dalam File atau Servlet JSP
Edit kode Anda ke persyaratan servlet, seperti ukuran file maksimum , ukuran permintaan maksimum dan opsi lain yang dapat Anda atur ...
sumber
Saya Menggunakan Servlet umum untuk setiap Formulir Html apakah memiliki lampiran atau tidak. Servlet ini mengembalikan tempat di
TreeMap
mana kuncinya adalah nama jsp Parameter dan nilai adalah Input Pengguna dan menyimpan semua lampiran dalam direktori tetap dan kemudian Anda mengganti nama direktori pilihan Anda. Koneksi di sini adalah antarmuka khusus kami yang memiliki objek koneksi. Saya pikir ini akan membantu Andasumber
Untuk Spring MVC saya telah mencoba selama berjam-jam untuk melakukan ini dan berhasil memiliki versi yang lebih sederhana yang berfungsi untuk mengambil input formulir baik data dan gambar.
Kontroler untuk menangani
Semoga bermanfaat :)
sumber
Sumber lain dari masalah ini terjadi jika Anda menggunakan Geronimo dengan Tomcat yang disematkan. Dalam hal ini, setelah banyak iterasi pengujian commons-io dan commons-fileupload, masalah muncul dari classloader induk yang menangani guci commons-xxx. Ini harus dicegah. Kecelakaan selalu terjadi di:
Perhatikan bahwa tipe daftar fileItems telah berubah dengan versi saat ini dari commons-fileupload menjadi khusus
List<FileItem>
sebagai lawan dari versi sebelumnya di mana itu generikList
.Saya menambahkan kode sumber untuk commons-fileupload dan commons-io ke proyek Eclipse saya untuk melacak kesalahan aktual dan akhirnya mendapatkan beberapa wawasan. Pertama, pengecualian yang dilemparkan adalah tipe Throwable bukan FileIOException yang disebutkan atau bahkan Exception (ini tidak akan terjebak). Kedua, pesan kesalahan membingungkan karena menyatakan kelas tidak ditemukan karena axis2 tidak dapat menemukan commons-io. Axis2 tidak digunakan dalam proyek saya sama sekali tetapi ada sebagai folder di subdirektori repositori Geronimo sebagai bagian dari instalasi standar.
Akhirnya, saya menemukan 1 tempat yang menghadirkan solusi kerja yang berhasil menyelesaikan masalah saya. Anda harus menyembunyikan guci dari pemuat induk dalam rencana penerapan. Ini dimasukkan ke geronimo-web.xml dengan file lengkap saya yang ditunjukkan di bawah ini.
sumber
Berikut ini contoh menggunakan apache commons-fileupload:
sumber
Cara paling sederhana bisa muncul untuk file dan kontrol input, tanpa satu miliar perpustakaan:
sumber
Anda dapat mengunggah file menggunakan jsp / servlet.
di sisi server sisi lain. gunakan kode berikut.
sumber
Dari objek ini Anda harus mendapatkan item file dan bidang kemudian Anda dapat menyimpan ke server seperti yang diikuti:
sumber
Mengirim beberapa file untuk file yang harus kita gunakan
enctype="multipart/form-data"
dan untuk mengirim banyak file
multiple="multiple"
dalam tag inputsumber
HALAMAN HTML
FILE SERVLET
web.xml
Kompilasi UploadServlet servlet di atas dan buat entri yang diperlukan dalam file web.xml sebagai berikut.
sumber