Cara mengkonfigurasi dan memecahkan masalah <p:fileUpload>
tergantung pada versi PrimeFaces.
Semua versi PrimeFaces
Persyaratan di bawah ini berlaku untuk semua versi PrimeFaces:
The enctype
atribut dari <h:form>
kebutuhan harus ditetapkan untuk multipart/form-data
. Jika ini tidak ada, unggahan ajax mungkin hanya berfungsi, tetapi perilaku browser umum tidak ditentukan dan bergantung pada komposisi formulir dan merek / versi browser web. Selalu tentukan agar aman.
Saat menggunakan mode="advanced"
(mis. Ajax upload, ini defaultnya), lalu pastikan Anda sudah memiliki <h:head>
template (master). Ini akan memastikan bahwa file JavaScript yang diperlukan disertakan dengan benar. Ini tidak diperlukan untuk mode="simple"
(unggahan non-ajax), tetapi ini akan merusak tampilan dan fungsionalitas semua komponen PrimeFaces lainnya, jadi Anda tetap tidak ingin melewatkannya.
Saat menggunakan mode="simple"
(misalnya, unggahan non-ajax), maka ajax harus dinonaktifkan pada setiap tombol / tautan perintah PrimeFaces oleh ajax="false"
, dan Anda harus menggunakan <p:fileUpload value>
dengan <p:commandButton action>
alih - alih <p:fileUpload fileUploadListener>
(untuk PrimeFaces <= 7.x) atau <p:fileUpload listener>
(untuk PrimeFaces> = 8.x)
Jadi, jika Anda ingin mengunggah file (otomatis) dengan dukungan ajax (ingatlah <h:head>
!):
<h:form enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{bean.upload}" auto="true" /> // for PrimeFaces >= 8.x this should be listener instead of fileUploadListener
</h:form>
public void upload(FileUploadEvent event) {
UploadedFile uploadedFile = event.getFile();
String fileName = uploadedFile.getFileName();
String contentType = uploadedFile.getContentType();
byte[] contents = uploadedFile.getContents(); // Or getInputStream()
// ... Save it, now!
}
Atau jika Anda ingin mengunggah file non-ajax:
<h:form enctype="multipart/form-data">
<p:fileUpload mode="simple" value="#{bean.uploadedFile}" />
<p:commandButton value="Upload" action="#{bean.upload}" ajax="false" />
</h:form>
private UploadedFile uploadedFile; // +getter+setter
public void upload() {
String fileName = uploadedFile.getFileName();
String contentType = uploadedFile.getContentType();
byte[] contents = uploadedFile.getContents(); // Or getInputStream()
// ... Save it, now!
}
Apakah dicatat bahwa atribut yang berhubungan dengan ajax seperti auto
, allowTypes
, update
, onstart
, oncomplete
, dll diabaikan dalam mode="simple"
. Jadi tidak perlu menentukannya dalam kasus seperti itu.
Perhatikan juga bahwa Anda harus membaca konten file segera di dalam metode yang disebutkan di atas dan bukan dalam metode kacang berbeda yang dipanggil oleh permintaan HTTP nanti. Ini karena konten file yang diunggah adalah permintaan yang tercakup dan dengan demikian tidak tersedia di permintaan HTTP nanti / berbeda. Upaya apa pun untuk membacanya di permintaan nanti kemungkinan besar akan berakhir java.io.FileNotFoundException
di file sementara.
PrimeFaces 8.x
Konfigurasi identik dengan info versi 5.x di bawah, tetapi jika pendengar Anda tidak dipanggil, periksa apakah attriubute dipanggil listener
dan tidak (seperti dengan versi 8.x sebelumnya)fileUploadListener
PrimeFaces 5.x
Ini tidak memerlukan konfigurasi tambahan jika Anda menggunakan JSF 2.2 dan Anda faces-config.xml
juga dinyatakan sesuai dengan versi JSF 2.2. Anda tidak memerlukan filter unggah file PrimeFaces sama sekali. Jika tidak jelas bagi Anda bagaimana cara menginstal dan mengkonfigurasi JSF dengan benar tergantung pada server target yang digunakan, buka Bagaimana cara menginstal dan mengkonfigurasi pustaka JSF dengan benar melalui Maven? dan bagian "Menginstal JSF" di halaman wiki JSF kami .
Namun, jika Anda belum menggunakan JSF 2.2 dan Anda tidak dapat memutakhirkannya (semestinya mudah ketika sudah menggunakan wadah yang kompatibel dengan Servlet 3.0), maka Anda perlu mendaftar secara manual filter unggah file PrimeFaces di bawah web.xml
(ini akan mengurai multi bagian permintaan dan isi peta parameter permintaan biasa sehingga FacesServlet
dapat terus bekerja seperti biasa):
<filter>
<filter-name>primeFacesFileUploadFilter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>primeFacesFileUploadFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
</filter-mapping>
The <servlet-name>
nilai facesServlet
harus sama persis nilai dalam <servlet>
masuknya javax.faces.webapp.FacesServlet
di sama web.xml
. Jadi jika itu misalnya Faces Servlet
, maka Anda perlu mengeditnya agar cocok.
PrimeFaces 4.x
Kisah yang sama seperti PrimeFaces 5.x berlaku di 4.x juga.
Hanya ada kemungkinan masalah dalam mendapatkan konten file yang diunggah dengan UploadedFile#getContents()
. Ini akan kembali null
ketika API asli digunakan sebagai ganti Apache Commons FileUpload. Anda perlu menggunakan UploadedFile#getInputStream()
sebagai gantinya. Lihat juga Bagaimana cara memasukkan gambar yang diupload dari p: fileUpload sebagai BLOB di MySQL?
Masalah potensial lainnya dengan API asli akan terlihat adalah ketika komponen unggahan ada dalam bentuk di mana permintaan ajax "biasa" yang berbeda diaktifkan yang tidak memproses komponen unggahan. Lihat juga Unggahan file tidak berfungsi dengan AJAX di PrimeFaces 4.0 / JSF 2.2.x - javax.servlet.ServletException: Jenis konten permintaan bukan data multipart / formulir .
Kedua masalah ini juga dapat diatasi dengan beralih ke FileUpload Apache Commons. Lihat bagian PrimeFaces 3.x untuk detailnya.
PrimeFaces 3.x
Versi ini tidak mendukung unggahan file asli JSF 2.2 / Servlet 3.0. Anda perlu menginstal FileUpload Apache Commons secara manual dan secara eksplisit mendaftarkan filter upload file web.xml
.
Anda membutuhkan perpustakaan berikut:
Mereka harus ada di classpath waktu proses aplikasi web. Saat menggunakan Maven, pastikan mereka setidaknya memiliki cakupan waktu proses (cakupan default kompilasi juga bagus). Saat membawa-bawa JAR secara manual, pastikan semuanya dimasukkan ke dalam /WEB-INF/lib
folder.
Detail pendaftaran filter unggah file dapat ditemukan di bagian PrimeFaces 5.x di sini di atas. Jika Anda menggunakan PrimeFaces 4+ dan Anda ingin secara eksplisit menggunakan FileUpload Apache Commons alih-alih mengunggah file asli JSF 2.2 / Servlet 3.0, maka Anda perlu di sebelah pustaka yang disebutkan dan memfilter juga parameter konteks di bawah ini di web.xml
:
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value><!-- Allowed values: auto, native and commons. -->
</context-param>
Penyelesaian masalah
Jika masih tidak berfungsi, berikut adalah kemungkinan penyebab lain yang tidak terkait dengan konfigurasi PrimeFaces:
Hanya jika Anda menggunakan PrimeFaces upload file filter: Ada satu lagi Filter
di webapp Anda yang berjalan sebelum para PrimeFaces upload file filter dan telah dikonsumsi tubuh permintaan misalnya panggilan getParameter()
, getParameterMap()
, getReader()
, dan sebagainya. Badan permintaan hanya dapat diurai sekali. Jika Anda memanggil salah satu metode tersebut sebelum filter upload file melakukan tugasnya, filter upload file akan mendapatkan isi permintaan kosong.
Untuk memperbaikinya, Anda harus menempatkan <filter-mapping>
filter unggahan file sebelum filter lainnya masuk web.xml
. Jika permintaan tersebut bukan multipart/form-data
permintaan, maka filter unggah file akan terus berlanjut seolah-olah tidak ada yang terjadi. Jika Anda menggunakan filter yang ditambahkan secara otomatis karena menggunakan anotasi (mis. PrettyFaces), Anda mungkin perlu menambahkan pengurutan eksplisit melalui web.xml. Lihat Bagaimana menentukan urutan eksekusi filter servlet menggunakan anotasi dalam WAR
Hanya jika Anda menggunakan filter unggah file PrimeFaces: Ada lagi Filter
di aplikasi web Anda yang berjalan sebelum filter unggah file PrimeFaces dan telah melakukan RequestDispatcher#forward()
panggilan. Biasanya, filter penulisan ulang URL seperti PrettyFaces melakukan ini. Ini memicu FORWARD
petugas operator, tetapi filter mendengarkan secara default REQUEST
hanya di petugas operator.
Untuk memperbaikinya, Anda harus meletakkan filter unggah file PrimeFaces sebelum filter penerusan, atau untuk mengkonfigurasi ulang filter unggahan file PrimeFaces untuk mendengarkan di FORWARD
operator juga:
<filter-mapping>
<filter-name>primeFacesFileUploadFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Ada yang bersarang <h:form>
. Ini ilegal di HTML dan perilaku browser tidak ditentukan. Seringkali, browser tidak mengirimkan data yang diharapkan saat dikirim. Pastikan Anda tidak bersarang <h:form>
. Ini sepenuhnya terlepas dari bentuknya enctype
. Hanya saja, jangan bentuk sarang sama sekali.
Jika Anda masih mengalami masalah, lakukan debug pada lalu lintas HTTP. Buka toolset pengembang webbrowser (tekan F12 di Chrome / Firebug23 + / IE9 +) dan periksa bagian Net / Network. Jika bagian HTTP terlihat baik-baik saja, maka debug kode JSF. Letakkan breakpoint FileUploadRenderer#decode()
dan maju dari sana.
Menyimpan file yang diunggah
Setelah Anda akhirnya berhasil, pertanyaan Anda berikutnya mungkin seperti "Bagaimana / di mana saya menyimpan file yang diunggah?". Nah, lanjutkan di sini: Cara menyimpan file yang diupload di JSF .
web.xml
sesuai Panduan Pengguna PrimeFaces. Apakah Anda tetap membacanya? Namun itu tidak akan menjelaskan mengapamode="simple"
berhasil untuk Anda.