How to set a bean property before uploading a file

2019-08-26 16:44发布

My application has a modal panel where the user can upload files and choose a "document type" in a drop-down select.

I was using an <f:setPropertyActionListener> to set the document type value during the upload event, but sometimes the property is set after the upload has been processed. Probably it's happening because another request is being generated, and this request is handled by another web container thread.

<rich:modalPanel id="attachFiles" autosized="true">
    <h:form id="formUpload" enctype="multipart/form-data">
        <h:selectOneMenu id="docType"  value="#{myMB.docType}" required="true" >
            <f:selectItems value="#{myMB.docTypesSelectItems}"  />
    </h:selectOneMenu>`
        <rich:fileUpload id="upload" fileUploadListener="#{myMB.handleUpload}">
            <a4j:support event="onupload">
                <f:setPropertyActionListener value="#{myMB.docType}" 
                    target="#{myMB.docType}" />
            </a4j:support>
        </rich:fileUpload>
</rich:modalPanel>

When it happens, the value of myMB.docTypeis null during the execution of myMB.handleUpload, which is not expected, since the field is supposed to be required.

Is there a way to assure that the method myMB.handleUpload is executed only after the property of docType has been set?

3条回答
小情绪 Triste *
2楼-- · 2019-08-26 17:19

I had a similar issue.

Change

<a4j:support event="onupload">

to

<a4j:support event="onclick">

The set document type action will be executed before upload file. Exactly when the explorer file system is opened

查看更多
该账号已被封号
3楼-- · 2019-08-26 17:30
<f:setPropertyActionListener value="#{myMB.docType}" target="#{myMB.docType}" />

I don't get you. The target is the same as the value. You're basically setting the target's value with self. Isn't the value itself simply already null?

Anyway, I don't do RichFaces, so I can't go in detail, but I know that it's using Flash under the covers for the upload component and that such a construction usually fires a separate (and standalone) request which doesn't take all other HTML form parameters into account. The "normal" JSF inputs comes thereafter in a separate HTTP request. So you're kind of lost here without bringing in some nasty JS/ajax hacks. At least, in theory.

Your best bet is to get hold of the uploaded file as a bean propery in the listener method and then process that further in the normal bean's action method (the one attached to some UICommand component in the same form).

查看更多
forever°为你锁心
4楼-- · 2019-08-26 17:45

I would add Ajax capability to the select component instead. This way, the bean value is immediately updated each time the user changes the value of the select. Inside your file uploading method you can then rely on the bean value to represent the most recent selection the user has made.

You would only have to take care of the case, where the user starts the file upload without touching the select. Either you would need to have a sensible default value or you would have to take care of a non-selection and make the select field somehow required before uploading a file.

查看更多
登录 后发表回答