8

Trying to implement the JSF 2.2 example I have the following code:

<h:form prependId="false" enctype="multipart/form-data">

    <!-- Now it's the AJAX file upload component -->
    <h:inputFile id="fileUpload" value="#{someBean.file}" >
        <f:ajax />
    </h:inputFile>

    <h:commandButton value="Upload" />
</h:form>

According to some JSF 2.2 this should work but in my case it is giving me the following error:

the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is application/x-www-form-urlencoded;charset=UTF-8

Looking into the request although I have set my form enctype correctly, the partial request submits:

Content-type:application/x-www-form-urlencoded;charset=UTF-8 Faces-Request:partial/ajax

Note that web.xml also was modified to:

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <multipart-config>
        <location>c:\dotmp</location>
        <max-file-size>20848820</max-file-size>
        <max-request-size>418018841</max-request-size>
        <file-size-threshold>1048576</file-size-threshold>
    </multipart-config>
</servlet>

I am using Mojarra 2.2.0-m15 but tried this with earlier versions as well. Does anyone know any useful info about this issue, which I assume is a bug?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Ioannis Deligiannis
  • 2,679
  • 5
  • 25
  • 48

3 Answers3

7

I'm not sure what's going on as I haven't seen this before. The following construct works for me when using the today's Mojarra 2.2.1 snapshot which you can download from the "implementation jar" link mentioned in What's new in JSF 2.2?

<h:form enctype="multipart/form-data">
    <h:inputFile value="#{bean.file}" required="true">
        <f:ajax listener="#{bean.handleFileUpload}" render="@form" />
    </h:inputFile>
    <h:messages />
</h:form>

with

private Part file;

public void handleFileUpload(AjaxBehaviorEvent event) {
    System.out.println("file size: " + file.getSize());
    System.out.println("file type: " + file.getContentType());
    System.out.println("file info: " + file.getHeader("Content-Disposition"));
}

// ...

I recommend to give the newer Mojarra version a try. Apparently there was a bug in an older Mojarra version which failed to create a proper multipart/form-data request using the <iframe> hack which ultimately caused this error. The mXX versions are beta versions anyway and should not be relied upon for production. This error could theoretically also have been browser-specific, but it works currently fine for me in Chrome 26, Firefox 20 and IE 10.

The only issue which I'm seeing is that the hidden <iframe> is still visible in Chrome and Firefox as below:

enter image description here

It appears that they're forgotten to set frameborder attribute to 0 in the generated <iframe>. I've reported issue 2861 about that.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the response BalusC. I got annoyed with JSF2.2 so switched back to latest release of JSF2.1 and used your Omnifaces render kit for html5. For the filwdownload I followed your tutorial from http://balusc.blogspot.co.uk/2009/12/uploading-files-in-servlet-30.html and surprisingly I got the exact same error. Caused by: org.apache.tomcat.util.http.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is application/x-www-form-urlencoded;charset=UTF-8 – Ioannis Deligiannis May 02 '13 at 15:16
  • Perhaps you're nesting forms? Would have been a rather obvious mistake though if you ever attempted to isolate the problem into a fullworthy SSCCE. – BalusC May 02 '13 at 15:19
  • Wish I was that lucky. What I have above is on it's own page as well as the code from your example. The is only one form and it only happens with when I submit using Ajax, otherwise it works fine. – Ioannis Deligiannis May 02 '13 at 15:33
  • The JSF 2.0 file upload component from my blog is not f:ajax compatible. The JSF 2.2 builtin file upload component is. – BalusC May 02 '13 at 15:41
  • I tried the jar you provided and it works fine. From what I can tell the javascript did not took into account the form type and made its own decision for the form type. Do you know a maven repository with the latest jsf2.2.1-SNAPSHOT ? – Ioannis Deligiannis May 02 '13 at 16:10
  • Glad it works for you. Maven details are available at https://javaserverfaces.java.net/download.html – BalusC May 02 '13 at 18:07
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29325/discussion-between-john-d-and-balusc) – Ioannis Deligiannis May 02 '13 at 18:13
2

I fixed the JavaScript of JSF (and other parts) to enable Multipart requests with and without AJAX on servlet standard 2.

The JSF 2.2 file upload works beginning with servlet version 3. Furthermore the responsible transport layer called "IFrame Transport" was not in release state. So I added a transparent Multipart request, completed the transport layer and put all together to an upload tag:

<e:inputFile id="file" value="#{fileUpload.file}" filename="#{fileUpload.filename}"
    mimeType="#{fileUpload.mimeType}"/>

The Tag works together with AJAX, with traditional page submits and with servlet standard 2 / 3. Not the nicest implementation, but it's working almost transparent. The solution is accessible at http://www.intersult.com/wiki/page/JSF%20Ext#section-JSF+Ext-FileUpload (Please use translation).

Comments welcomed.

Tires
  • 1,529
  • 16
  • 27
0

I had the same problem with PrimeFaces <p:fileUpload mode="simple" using javax.faces-2.2.6.jar. The problem disappeared when I disabled ajax from my <h:commandButton. In my case it was OK to refresh the whole page.

Panu Haaramo
  • 2,932
  • 19
  • 41