Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Ajax fileupload capabilities #802

Closed
glassfishrobot opened this issue May 17, 2010 · 45 comments
Closed

Ajax fileupload capabilities #802

glassfishrobot opened this issue May 17, 2010 · 45 comments

Comments

@glassfishrobot
Copy link

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....

Environment

Operating System: All
Platform: Macintosh

Affected Versions

[2.0]

@glassfishrobot
Copy link
Author

Reported by werpu12

@glassfishrobot
Copy link
Author

@glassfishrobot
Copy link
Author

@edburns said:
New features, 2.1.

@glassfishrobot
Copy link
Author

@edburns said:
triage

@glassfishrobot
Copy link
Author

@edburns said:
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().

@glassfishrobot
Copy link
Author

@edburns said:

      • Issue 647 has been marked as a duplicate of this issue. ***

@glassfishrobot
Copy link
Author

@edburns said:
adf keyword

@glassfishrobot
Copy link
Author

@edburns said:
Change target milestone.

@glassfishrobot
Copy link
Author

rogerk said:
triage - Folks have been asking for this.

@glassfishrobot
Copy link
Author

ganeshpuri said:
would be great to be able to do AJAX uploads with 2.1

@glassfishrobot
Copy link
Author

werpu12 said:
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.

@glassfishrobot
Copy link
Author

werpu12 said:
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
implementable.

(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.

@glassfishrobot
Copy link
Author

@edburns said:
Please make sure to look at https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?
id=690

@glassfishrobot
Copy link
Author

@glassfishrobot
Copy link
Author

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

http://www.jsftoolbox.com/documentation/tomahawk/09-TagReference/tomahawk-inputFileUpload.html

@glassfishrobot
Copy link
Author

@edburns said:
Even though Werner has done most of the preparatory work on this issue, I still have to move it to JSF
2.2.

@glassfishrobot
Copy link
Author

markcolletteice said:
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.

http://wiki.icefaces.org/display/ICE/FileEntry
http://www.icefaces.org/docs/v2_latest/ace/tld/ace/fileEntry.html
http://wiki.icefaces.org/display/ICE/Incremental+Upload+Processing+Using+FileEntryCallback

@glassfishrobot
Copy link
Author

ngriffin7a said:
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.

@glassfishrobot
Copy link
Author

tedgoddard said:
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)

@glassfishrobot
Copy link
Author

werpu12 said:
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.

@glassfishrobot
Copy link
Author

@edburns said:
Bulk assign all of Sheetal's spec issues to me.

@glassfishrobot
Copy link
Author

@edburns said:
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

@glassfishrobot
Copy link
Author

@edburns said:
Notes from merging in Neil's work.

@glassfishrobot
Copy link
Author

File: 20110613-i_spec_802_mods.txt
Attached By: @edburns

@glassfishrobot
Copy link
Author

@edburns said:
In progress patch.

@glassfishrobot
Copy link
Author

File: 20111208-i_spec_802-mods.patch
Attached By: @edburns

@glassfishrobot
Copy link
Author

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

@glassfishrobot
Copy link
Author

werpu12 said:
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)

@glassfishrobot
Copy link
Author

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

@glassfishrobot
Copy link
Author

@edburns said:
Move to sprint 11

@glassfishrobot
Copy link
Author

robweaver said:
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 ?

@glassfishrobot
Copy link
Author

@edburns said:
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.

http://java.net/jira/browse/GLASSFISH

Thanks,
Ed

@glassfishrobot
Copy link
Author

robweaver said:
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.

@glassfishrobot
Copy link
Author

rogerk said:
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.

@glassfishrobot
Copy link
Author

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

@glassfishrobot
Copy link
Author

@glassfishrobot
Copy link
Author

File: 20121102-werpu-AjaxFileupload.odt
Attached By: @edburns

@glassfishrobot
Copy link
Author

@edburns said:
Werner had some additional feedback.

@glassfishrobot
Copy link
Author

@arjantijms said:
As JSF 2.2 went final, shouldn't this issue be closed?

@glassfishrobot
Copy link
Author

rogerk said:
Fixed for 2.2

@glassfishrobot
Copy link
Author

Marked as fixed on Tuesday, April 30th 2013, 11:42:09 am

@glassfishrobot
Copy link
Author

jid1 said:
Did the "multiple" attribute make it into the spec?

@glassfishrobot
Copy link
Author

@edburns said:
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"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://xmlns.jcp.org/jsf/passthrough">
    <h:head></h:head>

    <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" />
           </h:inputFile>
        </p>
...

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.

@glassfishrobot
Copy link
Author

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

@glassfishrobot
Copy link
Author

This issue was imported from java.net JIRA JAVASERVERFACES_SPEC_PUBLIC-802

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants