Die Konfiguration und Fehlerbehebung <p:fileUpload>
hängt von der PrimeFaces-Version ab.
Alle PrimeFaces-Versionen
Die folgenden Anforderungen gelten für alle PrimeFaces-Versionen:
Das enctype
Attribut von <h:form>
muss auf gesetzt werden multipart/form-data
. Wenn dies nicht vorhanden ist, funktioniert der Ajax-Upload möglicherweise nur, aber das allgemeine Verhalten des Browsers ist nicht spezifiziert und hängt von der Zusammensetzung des Formulars und der Marke / Version des Webbrowsers ab. Geben Sie es einfach immer an, um auf der sicheren Seite zu sein.
Wenn Sie mode="advanced"
(dh Ajax-Upload, dies ist die Standardeinstellung) verwenden, stellen Sie sicher, dass Sie eine <h:head>
in der (Master-) Vorlage haben. Dadurch wird sichergestellt, dass die erforderlichen JavaScript-Dateien ordnungsgemäß enthalten sind. Dies ist für mode="simple"
(Nicht-Ajax-Upload) nicht erforderlich , würde jedoch das Erscheinungsbild und die Funktionalität aller anderen PrimeFaces-Komponenten beeinträchtigen, sodass Sie dies sowieso nicht verpassen möchten.
Bei der Verwendung von mode="simple"
(dh nicht-Ajax - Upload), dann muss Ajax deaktiviert werden auf alle PrimeFaces durch Tasten / Links - Befehl ajax="false"
, und Sie müssen verwenden <p:fileUpload value>
mit <p:commandButton action>
statt <p:fileUpload fileUploadListener>
(für PrimeFaces <= 7.x) oder <p:fileUpload listener>
(für PrimeFaces> = 8.x)
Wenn Sie also (automatisch) Dateien mit Ajax-Unterstützung hochladen möchten (beachten Sie die <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!
}
Oder wenn Sie eine Nicht-Ajax-Datei hochladen möchten:
<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!
}
Zu beachten ist, dass Ajax-bezogene Attribute wie auto
, allowTypes
,update
, onstart
, oncomplete
, etc. werden ignoriert in mode="simple"
. In diesem Fall müssen sie nicht angegeben werden.
Beachten Sie auch, dass Sie sollten den Dateiinhalt sofort in den oben genannten Methoden lesen und nicht in einer anderen Bean-Methode, die von einer späteren HTTP-Anforderung aufgerufen wird. Dies liegt daran, dass der Inhalt der hochgeladenen Datei einen Anforderungsbereich hat und daher in einer späteren / anderen HTTP-Anforderung nicht verfügbar ist. Jeder Versuch, es in einer späteren Anfrage zu lesen, endet höchstwahrscheinlich java.io.FileNotFoundException
in der temporären Datei.
PrimeFaces 8.x.
Die Konfiguration ist identisch mit den unten stehenden 5.x-Versionsinformationen. Wenn Ihr Listener jedoch nicht aufgerufen wird, überprüfen Sie, ob der attriubute aufgerufen wird listener
und nicht (wie bei Versionen vor 8.x).fileUploadListener
PrimeFaces 5.x.
Dies erfordert keine zusätzliche Konfiguration, wenn Sie JSF 2.2 verwenden und Ihre faces-config.xml
Version auch als konform JSF 2.2 deklariert ist. Sie benötigen den Filter zum Hochladen von PrimeFaces-Dateien überhaupt nicht. Falls Ihnen nicht klar ist, wie Sie JSF abhängig vom verwendeten Zielserver ordnungsgemäß installieren und konfigurieren können, lesen Sie Wie Sie JSF-Bibliotheken über Maven ordnungsgemäß installieren und konfigurieren. und "Installieren von JSF" auf unserer JSF-Wiki-Seite .
Wenn Sie JSF 2.2 jedoch noch nicht verwenden und es nicht aktualisieren können (sollte mühelos sein, wenn Sie bereits einen Servlet 3.0-kompatiblen Container verwenden), müssen Sie den folgenden Filter zum Hochladen von PrimeFaces-Dateien manuell registrieren web.xml
(er analysiert das Multi Teileanforderung und füllen Sie die reguläre Anforderungsparameterzuordnung aus, damit Sie FacesServlet
wie gewohnt weiterarbeiten können):
<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>
Der <servlet-name>
Wert von facesServlet
muss genau mit dem Wert im <servlet>
Eintrag des javax.faces.webapp.FacesServlet
in demselben übereinstimmen web.xml
. Wenn es also z Faces Servlet
.
PrimeFaces 4.x.
Die gleiche Geschichte wie bei PrimeFaces 5.x gilt auch für 4.x.
Es gibt nur ein potenzielles Problem beim Abrufen des hochgeladenen Dateiinhalts UploadedFile#getContents()
. Dies wird zurückgegeben, null
wenn die native API anstelle von Apache Commons FileUpload verwendet wird. Sie müssen UploadedFile#getInputStream()
stattdessen verwenden. Siehe auch Wie füge ich ein hochgeladenes Bild von p: fileUpload als BLOB in MySQL ein?
Ein weiteres potenzielles Problem mit der nativen API besteht darin, dass die Upload-Komponente in einer Form vorliegt, in der eine andere "reguläre" Ajax-Anforderung ausgelöst wird, die die Upload-Komponente nicht verarbeitet. Siehe auch Datei-Upload funktioniert nicht mit AJAX in PrimeFaces 4.0 / JSF 2.2.x - javax.servlet.ServletException: Der Anforderungsinhaltstyp ist kein Multipart / Formulardaten .
Beide Probleme können auch durch Umschalten auf Apache Commons FileUpload gelöst werden. Weitere Informationen finden Sie im Abschnitt PrimeFaces 3.x.
PrimeFaces 3.x.
Diese Version unterstützt das Hochladen nativer JSF 2.2 / Servlet 3.0-Dateien nicht. Sie müssen Apache Commons FileUpload manuell installieren und den Filter zum Hochladen von Dateien explizit registrieren web.xml
.
Sie benötigen folgende Bibliotheken:
Diese müssen im Laufzeitklassenpfad der Webanwendung vorhanden sein. Stellen Sie bei der Verwendung von Maven sicher, dass sie mindestens einen Laufzeitbereich haben (der Standardbereich für die Kompilierung ist ebenfalls gut). Stellen Sie beim manuellen Mitführen von JARs sicher, dass sie im /WEB-INF/lib
Ordner landen .
Die Registrierungsdetails für den Filter zum Hochladen von Dateien finden Sie oben im Abschnitt PrimeFaces 5.x. Wenn Sie PrimeFaces 4+ verwenden und Apache Commons FileUpload anstelle des nativen Hochladens von JSF 2.2 / Servlet 3.0-Dateien explizit verwenden möchten, müssen Sie neben den genannten Bibliotheken auch den folgenden Kontextparameter filtern in web.xml
:
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value><!-- Allowed values: auto, native and commons. -->
</context-param>
Fehlerbehebung
Falls es immer noch nicht funktioniert, gibt es noch weitere mögliche Ursachen, die nicht mit der PrimeFaces-Konfiguration zusammenhängen:
Nur wenn Sie die PrimeFaces Datei - Upload - Filter verwenden: Es gibt ein anderes Filter
in Ihrem Webapp , die ausgeführt wird, bevor die Filter PrimeFaces Datei - Upload und hat bereits den Wunsch Körper zB durch Berufung verbraucht getParameter()
, getParameterMap()
,getReader()
, und so weiter. Ein Anforderungshauptteil kann nur einmal analysiert werden. Wenn Sie eine dieser Methoden aufrufen, bevor der Filter zum Hochladen von Dateien seine Aufgabe erfüllt, erhält der Filter zum Hochladen von Dateien einen leeren Anforderungshauptteil.
Um dies zu beheben, müssen Sie <filter-mapping>
den Filter zum Hochladen von Dateien vor den anderen Filter setzen web.xml
. Wenn es sich bei der Anforderung nicht um eine multipart/form-data
Anforderung handelt, wird der Filter zum Hochladen von Dateien so fortgesetzt, als wäre nichts passiert. Wenn Sie Filter verwenden, die automatisch hinzugefügt werden, weil sie Anmerkungen verwenden (z. B. PrettyFaces), müssen Sie möglicherweise eine explizite Reihenfolge über web.xml hinzufügen. Siehe Definieren der Ausführungsreihenfolge von Servlet-Filtern mithilfe von Anmerkungen in WAR
Nur wenn Sie den Filter zum Hochladen von PrimeFaces-Dateien verwenden: Filter
In Ihrer Webanwendung befindet sich ein weiterer Filter, der vor dem Filter zum Hochladen von PrimeFaces-Dateien ausgeführt wird und einen RequestDispatcher#forward()
Aufruf ausgeführt hat. Normalerweise tun dies URL-Umschreibungsfilter wie PrettyFaces . Dies löst den FORWARD
Dispatcher aus, aber Filter überwachen standardmäßig REQUEST
nur den Dispatcher.
Um dies zu beheben, müssen Sie entweder den PrimeFaces-Filter zum Hochladen von Dateien vor den Weiterleitungsfilter stellen oder den PrimeFaces-Filter zum Hochladen von Dateien neu konfigurieren, um auch den FORWARD
Dispatcher abzuhören :
<filter-mapping>
<filter-name>primeFacesFileUploadFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Es gibt eine verschachtelte <h:form>
. Dies ist in HTML illegal und das Browserverhalten ist nicht angegeben. Mehr als oft sendet der Browser beim Senden nicht die erwarteten Daten. Stellen Sie sicher, dass Sie nicht verschachteln <h:form>
. Dies ist völlig unabhängig von der Form enctype
. Verschachteln Sie Formen überhaupt nicht.
Wenn Sie immer noch Probleme haben, debuggen Sie den HTTP-Verkehr. Öffnen Sie das Entwickler-Toolset des Webbrowsers (drücken Sie F12 in Chrome / Firebug23 + / IE9 +) und überprüfen Sie den Abschnitt Netz / Netzwerk. Wenn der HTTP-Teil gut aussieht, debuggen Sie den JSF-Code. Setzen Sie einen Haltepunkt FileUploadRenderer#decode()
und fahren Sie von dort fort.
Hochgeladene Datei speichern
Nachdem Sie es endlich zum Laufen gebracht haben, lautet Ihre nächste Frage wahrscheinlich "Wie / wo speichere ich die hochgeladene Datei?". Fahren Sie hier fort: So speichern Sie hochgeladene Dateien in JSF .
web.xml
gemäß dem PrimeFaces-Benutzerhandbuch registriert haben . Hast du es trotzdem gelesen? Das würde jedoch nicht erklären, warummode="simple"
für Sie funktioniert.