I am trying to upload a single file on JIRA for my plugin. Default JIRA upload behaviour is uploading the files via Ajax and converting them to checkboxes, thus enabling multiple file to be "uploaded" via one form type="file"
element (see the picture).
To disable inline attaching, class ignore-inline-attach
can be specified:
<form action="TestBrowse.jspa" id="upload-form" method="post" enctype="multipart/form-data">
<input type="hidden" name="id" value="10000"/>
<input type="file" name="uploadFile" class="ignore-inline-attach"/>
<input type="submit"/>
</form>
But then, when I try to get the MultipartRequestWrapper
in the servlet / action, I get nothing (this should be the way to go according to various sources, like here):
@Override
public String doExecute() throws Exception {
MultiPartRequestWrapper requestWrapper = ServletActionContext.getMultiPartRequest();
if (requestWrapper == null)
log.error("Why am I not getting a multipart wrapper?")
else {
...do something...
}
return returnCompleteWithInlineRedirect("/browse/" + getIssueObject().getKey());
}
Also, the enctype of the request seems to be application/x-www-form-urlencoded; charset=UTF-8
, although multipart/form-data
is clearly specified in the form template. Any ideas where I am making a mistake or some workaround?
This is a late answer but here's what I find out after 1 day investigating...
If your <input type="file">
is in a JIRA dialog, then the form is submitted using ajax. That's why the content type of the request is "application/x-www-form-urlencoded;"
. Try opening the link in a new browser tab and this problem disappears. You will receive a MultiPartRequestWrapper
in the server because the form is submitted normally(without ajax).
My first approach was to extend the JIRA.FormDialog
component to send a FormData
object with the file and other form inputs. This worked and the server recieved a multipart/form-data
request.
(edit)
The problem was returning the response to the dialog. I couldn't find a way to do this. The response always returned a complete JIRA page with the header and footer because somehow the server did not know that I was in the context of a Dialog.
I find out what was the problem. The parameters inline
and decorator
where not being reed by the server (appended to the FormData object). I tried adding these parameters to the action url and it worked:
<form ... action="MyUploadAction.jspa#if($action.isInlineDialogMode())?inline=true&decorator=dialog#end">
Here is the code:
var TEST = window.TEST || {};
TEST.FormDialog = JIRA.FormDialog.extend({
_getFormDataAsObject: function() {
var data = new FormData(this.$form[0]);
data.append('inline', true);
data.append('decorator', 'dialog');
return data;
}
});
JIRA.Dialogs.uploadFile = new TEST.FormDialog({
id: "dialog-id",
trigger: "a.dialog-trigger",
ajaxOptions: JIRA.Dialogs.getDefaultAjaxOptions,
onSuccessfulSubmit : JIRA.Dialogs.storeCurrentIssueIdOnSucessfulSubmit,
submitAjaxOptions: {
type: "post",
data: {
inline: true,
decorator: "dialog"
},
processData: false,
contentType: false,
mimeType: 'multipart/form-data',
dataType: "html"
}
});
Next I tried the FileReader
API. When the user changed the file input, I read the file and store its contents in the DOM. When the form is submitted via ajax, the file content is treated like a normal var. I did not like this approach very much because, if the file is big, then the webpage will take this unnecessary memory storing the contents.
Finally, I tried to use the JIRA approach (removing ignore-inline-attach
) for sending files as you enter them in the input. JIRA stores them as temporary files in the server. Then you must access them in the webwork action via the JIRA Attachment API. The downside with this approach is that it is possible to send multiple files but I just wanted to send a single file (like you).
Note that the last 2 approaches require two ways of handling the files in the server: 1) the normal MultiPartRequestWrapper
because the user can still open the dialog in a new page and the form is not submitted via ajax. 2) specific of the approach.
I ended up using the 1) approach after solving the response problem (mentioned above). HTH
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With