[JAVASERVERFACES_SPEC_PUBLIC-802] Ajax fileupload capabilities Created: 17/May/10  Updated: 23/Dec/13  Resolved: 30/Apr/13

Status: Closed
Project: javaserverfaces-spec-public
Component/s: Ajax/JavaScript
Affects Version/s: 2.0
Fix Version/s: 2.2

Type: Improvement Priority: Critical
Reporter: werpu12 Assignee: Ed Burns
Resolution: Fixed Votes: 10
Labels: None
Remaining Estimate: 6 days, 8 hours, 3 minutes
Time Spent: 15 hours, 57 minutes
Original Estimate: 1 week

Operating System: All
Platform: Macintosh

Attachments: Text File 20110613-i_spec_802_mods.txt     Text File 20111208-i_spec_802-mods.patch     File 20121102-werpu-AjaxFileupload.odt    
Issue Links:
depends on GLASSFISH-16740 Unable to get "multipart/form-data" r... Resolved
depends on JAVASERVERFACES_SPEC_PUBLIC-149 Provide way to discover the JSF spec ... Closed
blocks JAVASERVERFACES-2573 Implement "ajax" file upload Closed
is related to JAVASERVERFACES_SPEC_PUBLIC-1197 Support multiple attribute on h:input... Open
is related to JAVASERVERFACES-3122 Migrate test for spec issue #802 to t... Closed
Issuezilla Id: 802
Status Whiteboard:

size_medium importance_large draft

Tags: adf


The main issue with the current implementation is, that fileupload the ajax way
is not working properly.

The problem simply is, that fileupload component and multipart form requests
both are a second class citizen in the JEE world and html generally.
There is no way to submit a fileupload via ajax currently, however there is an
iframe based method to do it.

But for that an iframe transport layer is missing, since the current spec only
talks abut queued asynchronous xhr requests.

see http://www.openjs.com/articles/ajax/ajax_file_upload/

for more information....

Comment by Ed Burns [ 24/May/10 ]

New features, 2.1.

Comment by Ed Burns [ 08/Jun/10 ]


Comment by Ed Burns [ 08/Jun/10 ]

Comments from issue 647 Note that from a spec perspective, I believe that the main issue is that
jsf.ajax.response() expects a XHR
object, which it uses to grab the responseXML. However, XHR cannot be used in the multi-part form case
(requires iframe-based postback), and as such no XHR object is available to pass off to jsf.ajax.response().

Comment by Ed Burns [ 08/Jun/10 ]
      • Issue 647 has been marked as a duplicate of this issue. ***
Comment by Ed Burns [ 08/Jun/10 ]

adf keyword

Comment by Ed Burns [ 24/Jun/10 ]

Change target milestone.

Comment by rogerk [ 30/Jun/10 ]

triage - Folks have been asking for this.

Comment by ganeshpuri [ 30/Jun/10 ]

would be great to be able to do AJAX uploads with 2.1

Comment by werpu12 [ 09/Jul/10 ]

Ok I am doing some prototyping on this issue within the realms of myfaces (since
I am not allowed to do that for Mojarra)
So far I have something preliminary up and running which has yet to be committed
which pushes the current lifecycle over iframes insteas of xhr. However I found
something in the spec which is some sort of a blocker. The spec requires for a
valid ajax request that Faces-Request:partial/ajax is set in the request header.
I do not think you can tamper on form level (which in fact the iframe solution
is) with that. The result of leaving it out is that the impl thinks this is not
an ajax request and then renders the full page instead of the response xml.

I am going to investigate further if setting the request header is possible on
the iframe solution. Otherwise we have to revamp the spec here a little bit.

Comment by werpu12 [ 14/Jul/10 ]

Ok the issue with the current specification in the ajax dection and triggering
of the partial mechanisms is following. I was able to patch the
PartialViewHandler up so that the entire lifecycle works with the iframe transport.

The problem really is we currently have two mechanisms, one identifying that it
is a partial request, the other one, that it is an Ajax request.
Both work over request headers, for the iframe case we have to weaken the spec
here a little bit to allow the same over
request parameters, since there seems to be no way to submit a new header param
via a normal form submit.

The idea is following, introduce a third type, iframe request, and allow both
ajax request, iframe request and partial request also be submitted over simple
request parameters instead of header params (so both type of values can trigger
a valid partial lifecycle a request header parameter or a normal request parameter)
Once a valid iframe request can trigger the partial lifecycle everything else
behaves just as it would in the xhr case (for the server both usecases are just
post requests)

As for the proposed mechanism. My personal idea is to enqueue an iframe request
just like we would a normal xhr post request in our asynchronous queue and just
treat it from outside like we we an xhr request. I have this running for most
browsers already I just have a sync issue for heavy load on IE6, which I will
investigate later into, but the pattern looks good to me that it might be

(see the preliminary snapshot code here http://www.pastebin.org/396667 and
http://www.pastebin.org/396646 from my myfaces based prototype)
The reason for this is synchronisation issues which the queue eliminates.

As how and when we trigger the mechanism is a little bit unclear to me still, my
personal guess is that an auto switch between xhr and iframe in case of an
embedded executed fileupload might make the most sense to keep the api simple),
I will try to find out more once my prototype can finally do the fileupload.

Comment by Ed Burns [ 28/Jul/10 ]

Please make sure to look at https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?

Comment by Ed Burns [ 28/Jul/10 ]

Also make sure to look at https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=861

Comment by Ed Burns [ 29/Jul/10 ]

Werner suggests the attribute set for t:inputFileUpload as a guide


Comment by Ed Burns [ 02/Sep/10 ]

Even though Werner has done most of the preparatory work on this issue, I still have to move it to JSF

Comment by markcolletteice [ 14/Apr/11 ]

In ICEfaces ACE, the fileEntry component uses the [hidden] iframe technique. We have to fake out the partial/ajax request, as well as extract the uploaded file(s) and translate the multi-part request to not be multi-part, so that JSF will run. And then in the browser, when handling the response, we have to fake out the XHR response object, using what we get from the iframe response, so that page updates will be handled.

It would be nice to collaborate on moving parts of this into JSF, so that everyone's different file upload components could be built on a common infrastructure.

One critical issue to us is that we don't follow the pattern of simply sticking the file contents into a temporary byte[] or file, like the other component frameworks do. We allow for either directly writing the file to the end file-system destination that the application specified, or using a callback interface for chunking the file data, without buffering the whole file, to the application, so that it can virus scan the file contents, or re-transmit it to another server via a socket, or write it to a database. So, we'd like the file processing to be custom for the component framework, that way we're not limited by a lowest common denominator handling of file data.


Comment by Neil Griffin [ 19/Apr/11 ]

I'm very happy to see that Ajax-based file upload is being discussed. But for the sake of completeness, I think that the old Web 1.0 multipart/form-data technique should be supported, as was discussed in http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-690

In my comments there,mentioned that I implemented a solution in the PortletFaces Bridge. It's working quite nicely – no need for Servlet 3.0, no need for a filter. Everything works great. Making this work in a Servlet-based JSF like Mojarra should be a piece of cake.

Comment by tedgoddard [ 21/Apr/11 ]

The approach to resolving this should be to provide additional APIs that make it possible to plug different transports into the JSF request/response cycle:

  • allow a partial response to be requested without a custom HTTP header
  • support new HTML5/XMLHttpRequest features that include file parts
  • expose JSF form serialization to String as JavaScript API
  • ensure that jsf.ajax.response can easily be called by external code (context and jsfResponse do not seem to be entirely public parameters)
Comment by werpu12 [ 21/Apr/11 ]

Actually that is how we prototyped it for myfaces. We dont have an official api, but we have configuration options which allow to choose a certain transport type.

So you can define jsf.ajax.request with additional myfaces:

{transportType: "iframeRequest"}

etc.. options to force the system into an iframe request.

We also allow an auto transport option where the system changes from the default xhr level1 into iframe if a multipart file upload situation is detected.

The problem with xhr level3 simply is or was the last time I looked at it that most browsers issued multipart requests without length attributes which rendered most fileupload libraries useless (and broke one of the two related specs in that area)
so an auto fallback to xhr level3 is definitely given the state of affairs a no go.

But as I see it xhr level3 is a good option if you can support it properly because it also allows some kind of progress notification so if this issue is started we also should opt for xhr level3 optionally.

The http header issue was another one. Currently the jsf ajax cycle is determined over custom http header, which is a no go in an iframe scenario because you only can send parameters, this needs to be fixed (and I did an internal fallback in myfaces to fix this but this is currently an implementation detail.

the jsf.ajax.response is another issue relatively unrelated, in myfaces we have some internal params which fix some internal issues, like how do you fix the issue of having an update and your original element is detached as well as its parent form. Those kind issues simply have to be taken care of in the official spec then I guess the jsf.ajax.response is really public.
I guess mojarra has 1-2 of those extra bugfix params as well.
But actually in case of myfaces I just got this bugreport in and it indeed is a bug in our impl because the call to the jsf.ajax.response should work without any extra params.

Comment by Ed Burns [ 06/Jun/11 ]

Bulk assign all of Sheetal's spec issues to me.

Comment by Ed Burns [ 08/Dec/11 ]

Neil committed his version of the work to https://svn.java.net/svn/mojarra~svn/branches/FILE_UPLOAD

These are the files that differ from the state of the tree when he created that branch.

These files were committed in r9162.

Index: common/ant/dependencies.xml
Index: jsf-api/doc/file-props.xml
Index: jsf-api/doc/standard-html-renderkit-base.xml
Index: jsf-api/doc/standard-html-renderkit.xml
Index: jsf-api/src/main/java/javax/faces/component/UploadedFile.java
Index: jsf-ri/conf/share/html_basic.taglib.xml
Index: jsf-ri/src/main/java/com/sun/faces/context/ExternalContextImpl.java
Index: jsf-ri/src/main/java/com/sun/faces/context/RequestParameterMapMultiPartImpl.java
Index: jsf-ri/src/main/java/com/sun/faces/context/RequestParameterMapFactory.java
Index: jsf-ri/src/main/java/com/sun/faces/context/RequestParameterValuesMapMultiPartImpl.java
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/html/HtmlDecorator.java
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/html/HtmlLibrary.java
Index: jsf-ri/src/main/java/com/sun/faces/renderkit/html_basic/FileRenderer.java
Index: jsf-ri/src/main/java/com/sun/faces/renderkit/html_basic/TextRenderer.java
Index: jsf-ri/src/main/java/com/sun/faces/component/UploadedFileImpl.java
Index: jsf-ri/src/main/resources/com/sun/faces/standard-html-renderkit-impl.xml

Comment by Ed Burns [ 08/Dec/11 ]

Notes from merging in Neil's work.

Comment by Ed Burns [ 08/Dec/11 ]

In progress patch.

Comment by Ed Burns [ 09/Dec/11 ]

@edburns Will JSF's AJAX file upload offer functions to display progress? Or suport multi-file uploads?

Comment by werpu12 [ 09/Dec/11 ]

Progress is not possible with existing html means, XHR Level 2 in the long run will support it. Not sure if the spec can specifiy a progress event which if supported can be fired and if not does nothing except to go from 0 to 100, it would make sense. Same I think goes for multiple file uploads.
(Cannot remember if the existing iframe method supports multiple file uploads)

Comment by Ed Burns [ 16/Dec/11 ]

Move to Sprint 10, but at leas we have the non-Ajax portion committed.

Comment by Ed Burns [ 03/Feb/12 ]

Move to sprint 11

Comment by robweaver [ 13/Apr/12 ]

Just updated to 3.1.2 (Build 23) and the FileUpload on PrimeFaces broke (I think due to this issue).

Upload widget acts as if the upload is working, but never hits the back end event handler.

Reverting to 3.1 with no changes to WAR and the file upload works again.

Would be glad to help diagnose this issue.

Any target date for the fix, and is there a workaround ?

Comment by Ed Burns [ 13/Apr/12 ]

Hello robweaver,

Can I ask you please to file this in the GLASSFISH JIRA? I know some multipart upload changes were done in GlassFish 3.1.2 and t's quite possible this has nothing to do with Mojarra JSF implementation. At any rate, it certainly doesn't have anything to do with the spec.



Comment by robweaver [ 15/Apr/12 ]

Thanks, I thought I was entering it on the GlassFish issue, sorry see http://java.net/jira/browse/GLASSFISH-18444 which appears to be my issue.

Apologies for the incorrect entry.

Comment by rogerk [ 23/May/12 ]

There currently is a bug in the implementation - see: http://java.net/jira/browse/JAVASERVERFACES-2420. However, if the page author specifies a "value" attribute it should be rendered.

Comment by Ed Burns [ 15/Oct/12 ]

Werner prepared this document prior to a 60 minute Google+ hangout we had today. We edited the document during the meeting.

Comment by Ed Burns [ 16/Oct/12 ]

See < http://tim-vm9.us.oracle.com:7070/hudson/job/trunk-test-glassfish-4_0/442/ >.

Comment by Ed Burns [ 06/Nov/12 ]

Werner had some additional feedback.

Comment by arjan tijms [ 30/Apr/13 ]

As JSF 2.2 went final, shouldn't this issue be closed?

Comment by rogerk [ 30/Apr/13 ]

Fixed for 2.2

Comment by jid1 [ 03/Jun/13 ]

Did the "multiple" attribute make it into the spec?

Comment by Ed Burns [ 10/Jun/13 ]

Well, yes and no. I just tested it.

Here's the yes part.

You can say this:

<html xmlns="http://www.w3.org/1999/xhtml"

    <h:form id="form" enctype="multipart/form-data" prependId="false">
        <p><h:inputFile id="file" value="#{fileUploadBean.uploadedFile}" p:multiple="multiple"> 
             <f:validator validatorId="FileValidator" />

and it renders correctly:

        <p><input id="file" type="file" name="file" multiple="multiple" />

but the no part is that each of the files in the multiple list is overwritten when the next one is processed.

Comment by Ed Burns [ 10/Jun/13 ]

I have filed < https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1197 > to cover this. We'll get to it in 2.3.

Generated at Fri Oct 28 22:43:02 UTC 2016 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.