Important : The issue which is discussed in this thread has been fixed as of PrimeFaces 5.1 final (community release) released on Monday, October 6, 2014 (just a few minutes ago from now). I attempted on JSF 2.2.8-02 (or api, impl).
As such, if you happened to use that version (or higher, no need to mention), you would not even need to read this question anymore.
I have a web application running on
Everything except file upload with AJAX works well. The following xhtml file sends multipart contents via an AJAX request triggered by a PrimeFaces command button.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form prependId="true" enctype="multipart/form-data">
<p:fileUpload id="txtCatImage"
value="#{testManagedBean.uploadedFile}"
mode="advanced"
dragDropSupport="true"
fileLimit="1"
sizeLimit="100000"
multiple="false"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
fileUploadListener="#{testManagedBean.fileUploadListener}"/>
<p:message for="txtCatImage" showSummary="false"/>
<p:commandButton id="btnSubmit"
actionListener="#{testManagedBean.insert}"
ajax="true" icon="ui-icon-check" value="Save"/>
</h:form>
</h:body>
</html>
The test managed bean:
@ManagedBean
@ViewScoped
public final class TestManagedBean implements Serializable {
private static final long serialVersionUID = 1L;
private UploadedFile uploadedFile;
public TestManagedBean(){}
public UploadedFile getUploadedFile() {
return uploadedFile;
}
public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}
public void fileUploadListener(FileUploadEvent event){
uploadedFile=event.getFile();
}
public void insert(){
if(uploadedFile!=null){
System.out.println(uploadedFile.getFileName());
}
else{
System.out.println("The file object is null.");
}
}
}
When a file is uploaded from a file browser, it shows the file name in its listener - fileUploadListener()
.
After uploading a file, when the given command button is pressed (ajax="true"
), it causes the following exception to be thrown.
WARNING: javax.servlet.ServletException: The request content-type is not a multipart/form-data
javax.faces.FacesException: javax.servlet.ServletException: The request content-type is not a multipart/form-data
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:44)
at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:44)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
at javax.faces.component.UIInput.decode(UIInput.java:771)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
at javax.faces.component.UIForm.processDecodes(UIForm.java:225)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:929)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:70)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at filter.NoCacheFilter.doFilter(NoCacheFilter.java:28)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.servlet.ServletException: The request content-type is not a multipart/form-data
at org.apache.catalina.fileupload.Multipart.getPart(Multipart.java:187)
at org.apache.catalina.connector.Request.getPart(Request.java:4535)
at org.apache.catalina.connector.RequestFacade.getPart(RequestFacade.java:1095)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:60)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:37)
... 48 more
SEVERE: javax.servlet.ServletException: The request content-type is not a multipart/form-data
at org.apache.catalina.fileupload.Multipart.getPart(Multipart.java:187)
at org.apache.catalina.connector.Request.getPart(Request.java:4535)
at org.apache.catalina.connector.RequestFacade.getPart(RequestFacade.java:1095)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:60)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:37)
at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:44)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
at javax.faces.component.UIInput.decode(UIInput.java:771)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
at javax.faces.component.UIForm.processDecodes(UIForm.java:225)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:929)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:70)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at filter.NoCacheFilter.doFilter(NoCacheFilter.java:28)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:722)
It can only work, when the ajax attribute of the command button is set to false - ajax="false"
.
I have downgraded the Mojarra version to 2.1.9 in Tomcat 7.0.35. It worked with this Mojarra version along with PrimeFaces 4.0 final (and PrimeFaces 4.0 RC1 too) - files uploaded with an AJAX request.
I have alternatively tried on the following Mojarra versions
in GlassFish 4.0 but none of them succeeded to upload files with an AJAX request which is highly required because editing of rows using <p:rowEditor/>
(along with images in each row, for example) in PrimeFaces DataTable is always AJAX based.
I want to keep GlassFish 4.0 anyhow. I have also tried to downgrade Mojarra 2.1.9 in GlassFish 4.0 but it failed to create bundles ending with an exception. GlassFish 4.0 doesn't seem to work with Mojarra lower than 2.2.x.
So, what is responsible for causing this exception - PrimeFaces or JSF? Just confused. Is there any workaround to upload files with AJAX requests in this given environment?
EDIT:
Filter mapping in web.xml
:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
The problem remains stationary along with the Mojarra version 2.2.5 (or api, impl) released on January 08, 2014.
Once again tried on the Mojarra version 2.2.6 (or api, impl) released on March 04, 2014. The problem remains intact.
Still does not work on PrimeFaces 5.0 final released on May 05, 2014.
I had the same issue. It seems to be more related to the <p:commandButton>
than the <p:fileUpload>
component, since it works with an <h:commandButton>
(even with ajax).
You could try:
<h:commandButton id="btnSubmit" actionListener="#{testManagedBean.insert}" value="Save">
<f:ajax execute="@all" render="@form"/>
</h:commandButton>
I cannot tell you why or how it works, but it fixed the issue for me. The downside of course is, that you have to do the styling by yourself, at least until the Primefaces guys fix this issue.
EDIT:
After digging in the sources and doing some debugging if figured out that there are actually two requests made (I tried in <p:wizard/>
). The first one is the multipart/form-data
one which actually does the file upload. It fires the fileUploadEvent in the Bean. I the wizards next button is pressed another form with enctype application/www-urlencoded
is submitted. This causes the exception. Conclusion is, that unlike what I wrote in the comment suppressing the exception is a valid solution. This can even be done in a way that does not include changing the Primefaces.jar which is handy if the guys fix the issue in a future version.
So here is what needs to be done:
com.yourpackage.fileupload.FileUploadRenderer
Copy and paste the following code inside your new class:
package com.yourpackage.fileupload.fileupload;
import java.io.IOException;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.servlet.http.HttpServletRequest;
import org.primefaces.component.fileupload.CommonsFileUploadDecoder;
import org.primefaces.component.fileupload.FileUpload;
import org.primefaces.component.fileupload.NativeFileUploadDecoder;
import org.primefaces.config.ConfigContainer;
import org.primefaces.context.RequestContext;
import org.primefaces.expression.SearchExpressionFacade;
import org.primefaces.renderkit.CoreRenderer;
import org.primefaces.util.HTML;
import org.primefaces.util.WidgetBuilder;
public class FileUploadRenderer extends CoreRenderer {
@Override
public void decode(FacesContext context, UIComponent component) {
FileUpload fileUpload = (FileUpload) component;
if (!fileUpload.isDisabled()) {
ConfigContainer cc = RequestContext.getCurrentInstance().getApplicationContext().getConfig();
String uploader = cc.getUploader();
boolean isAtLeastJSF22 = cc.isAtLeastJSF22();
if (uploader.equals("auto")) {
if (isAtLeastJSF22) {
if (isMultiPartRequest(context)) {
NativeFileUploadDecoder.decode(context, fileUpload);
}
} else {
CommonsFileUploadDecoder.decode(context, fileUpload);
}
} else if (uploader.equals("native")) {
if (!isAtLeastJSF22) {
throw new FacesException("native uploader requires at least a JSF 2.2 runtime");
}
NativeFileUploadDecoder.decode(context, fileUpload);
} else if (uploader.equals("commons")) {
CommonsFileUploadDecoder.decode(context, fileUpload);
}
}
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
FileUpload fileUpload = (FileUpload) component;
encodeMarkup(context, fileUpload);
if (fileUpload.getMode().equals("advanced")) {
encodeScript(context, fileUpload);
}
}
protected void encodeScript(FacesContext context, FileUpload fileUpload) throws IOException {
String clientId = fileUpload.getClientId(context);
String update = fileUpload.getUpdate();
String process = fileUpload.getProcess();
WidgetBuilder wb = getWidgetBuilder(context);
wb.initWithDomReady("FileUpload", fileUpload.resolveWidgetVar(), clientId, "fileupload");
wb.attr("auto", fileUpload.isAuto(), false)
.attr("dnd", fileUpload.isDragDropSupport(), true)
.attr("update", SearchExpressionFacade.resolveComponentsForClient(context, fileUpload, update), null)
.attr("process", SearchExpressionFacade.resolveComponentsForClient(context, fileUpload, process), null)
.attr("maxFileSize", fileUpload.getSizeLimit(), Long.MAX_VALUE)
.attr("fileLimit", fileUpload.getFileLimit(), Integer.MAX_VALUE)
.attr("invalidFileMessage", fileUpload.getInvalidFileMessage(), null)
.attr("invalidSizeMessage", fileUpload.getInvalidSizeMessage(), null)
.attr("fileLimitMessage", fileUpload.getFileLimitMessage(), null)
.attr("messageTemplate", fileUpload.getMessageTemplate(), null)
.attr("previewWidth", fileUpload.getPreviewWidth(), 80)
.attr("disabled", fileUpload.isDisabled(), false)
.callback("onstart", "function()", fileUpload.getOnstart())
.callback("onerror", "function()", fileUpload.getOnerror())
.callback("oncomplete", "function()", fileUpload.getOncomplete());
if (fileUpload.getAllowTypes() != null) {
wb.append(",allowTypes:").append(fileUpload.getAllowTypes());
}
wb.finish();
}
protected void encodeMarkup(FacesContext context, FileUpload fileUpload) throws IOException {
if (fileUpload.getMode().equals("simple")) {
encodeSimpleMarkup(context, fileUpload);
} else {
encodeAdvancedMarkup(context, fileUpload);
}
}
protected void encodeAdvancedMarkup(FacesContext context, FileUpload fileUpload) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = fileUpload.getClientId(context);
String style = fileUpload.getStyle();
String styleClass = fileUpload.getStyleClass();
styleClass = styleClass == null ? FileUpload.CONTAINER_CLASS : FileUpload.CONTAINER_CLASS + " " + styleClass;
boolean disabled = fileUpload.isDisabled();
writer.startElement("div", fileUpload);
writer.writeAttribute("id", clientId, "id");
writer.writeAttribute("class", styleClass, styleClass);
if (style != null) {
writer.writeAttribute("style", style, "style");
}
//buttonbar
writer.startElement("div", fileUpload);
writer.writeAttribute("class", FileUpload.BUTTON_BAR_CLASS, null);
//choose button
encodeChooseButton(context, fileUpload, disabled);
if (!fileUpload.isAuto()) {
encodeButton(context, fileUpload.getUploadLabel(), FileUpload.UPLOAD_BUTTON_CLASS, "ui-icon-arrowreturnthick-1-n");
encodeButton(context, fileUpload.getCancelLabel(), FileUpload.CANCEL_BUTTON_CLASS, "ui-icon-cancel");
}
writer.endElement("div");
//content
writer.startElement("div", null);
writer.writeAttribute("class", FileUpload.CONTENT_CLASS, null);
writer.startElement("table", null);
writer.writeAttribute("class", FileUpload.FILES_CLASS, null);
writer.startElement("tbody", null);
writer.endElement("tbody");
writer.endElement("table");
writer.endElement("div");
writer.endElement("div");
}
protected void encodeSimpleMarkup(FacesContext context, FileUpload fileUpload) throws IOException {
encodeInputField(context, fileUpload, fileUpload.getClientId(context));
}
protected void encodeChooseButton(FacesContext context, FileUpload fileUpload, boolean disabled) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = fileUpload.getClientId(context);
String cssClass = HTML.BUTTON_TEXT_ICON_LEFT_BUTTON_CLASS + " " + FileUpload.CHOOSE_BUTTON_CLASS;
if (disabled) {
cssClass += " ui-state-disabled";
}
writer.startElement("span", null);
writer.writeAttribute("class", cssClass, null);
//button icon
writer.startElement("span", null);
writer.writeAttribute("class", HTML.BUTTON_LEFT_ICON_CLASS + " ui-icon-plusthick", null);
writer.endElement("span");
//text
writer.startElement("span", null);
writer.writeAttribute("class", HTML.BUTTON_TEXT_CLASS, null);
writer.writeText(fileUpload.getLabel(), "value");
writer.endElement("span");
if (!disabled) {
encodeInputField(context, fileUpload, clientId + "_input");
}
writer.endElement("span");
}
protected void encodeInputField(FacesContext context, FileUpload fileUpload, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", null);
writer.writeAttribute("type", "file", null);
writer.writeAttribute("id", clientId, null);
writer.writeAttribute("name", clientId, null);
if (fileUpload.isMultiple()) {
writer.writeAttribute("multiple", "multiple", null);
}
if (fileUpload.getStyle() != null) {
writer.writeAttribute("style", fileUpload.getStyle(), "style");
}
if (fileUpload.getStyleClass() != null) {
writer.writeAttribute("class", fileUpload.getStyleClass(), "styleClass");
}
if (fileUpload.isDisabled()) {
writer.writeAttribute("disabled", "disabled", "disabled");
}
writer.endElement("input");
}
protected void encodeButton(FacesContext context, String label, String styleClass, String icon) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String cssClass = HTML.BUTTON_TEXT_ICON_LEFT_BUTTON_CLASS + " ui-state-disabled " + styleClass;
writer.startElement("button", null);
writer.writeAttribute("type", "button", null);
writer.writeAttribute("class", cssClass, null);
writer.writeAttribute("disabled", "disabled", null);
//button icon
String iconClass = HTML.BUTTON_LEFT_ICON_CLASS;
writer.startElement("span", null);
writer.writeAttribute("class", iconClass + " " + icon, null);
writer.endElement("span");
//text
writer.startElement("span", null);
writer.writeAttribute("class", HTML.BUTTON_TEXT_CLASS, null);
writer.writeText(label, "value");
writer.endElement("span");
writer.endElement("button");
}
private boolean isMultiPartRequest(FacesContext context) {
if (context == null) {
return false;
}
return ((HttpServletRequest) context.getExternalContext().getRequest()).getContentType().startsWith("multipart");
}
}
Add the following lines at the bottom of your faces-config.xml
:
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.FileUploadRenderer</renderer-type>
<renderer-class>com.yourpackage.fileupload.FileUploadRenderer</renderer-class>
</renderer>
</render-kit>
You're ready to go!
What have we done? We created our own FileUploadRenderer which checks if the contentType is really multipart/form-data
using the method isMultiPartRequest()
. Only if this returns true the rest of the code is executed. In any other case nothing will happen which means that no exception will be thrown. If Primefaces fixes this issue you just need to remove the lines from your faces-config.xml
to use their class.
Let me know if that works for you!
EDIT
This code checks wether or not the given request is of type multipart/form-data. If it is not the execution is stopped. The original Primefaces code would continue anyway. As I mentioned above if you upload a file inside a Primefaces component there are actually two requests made:
<p:fileUpload/>
(enctype: multipart/form-data
)<p:editRow/>
or <p:wizard/>
(enctype: application/www-form-urlencoded
)The first one is handled by the renderer while the second one causes the exception in the original code since the renderer tries to handle something which it is not capable of. With the changes made in the code only multipart/form-data
forms are handled by the renderer so no exceptions occur. IMO it is clearly a bug in the sources of Primefaces. The code differences is just the method private boolean isMultiPartRequest(FacesContext context)
and its one occurrence in the code. Glad I could help you!