5

我正在尝试为我的插件在 JIRA上上传一个文件。默认的 JIRA 上传行为是通过 Ajax 上传文件并将它们转换为复选框,从而使多个文件能够通过一个表单type="file"元素“上传”(见图)。

附加的文件

要禁用内联附加,ignore-inline-attach可以指定类:

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

但是,当我尝试MultipartRequestWrapper在 servlet / action 中获取时,我什么也得不到(根据各种来源,这应该是要走的路,比如这里):

@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());
}

此外,请求的 enctype 似乎是application/x-www-form-urlencoded; charset=UTF-8,尽管multipart/form-data在表单模板中明确指定。有什么想法我犯了错误或一些解决方法吗?

4

1 回答 1

2

这是一个迟到的答案,但这是我在调查 1 天后发现的......

如果您<input type="file">在 JIRA 对话框中,则使用 ajax 提交表单。这就是为什么请求的内容类型是"application/x-www-form-urlencoded;". 尝试在新的浏览器选项卡中打开链接,此问题就会消失。您将MultiPartRequestWrapper在服务器中收到一个,因为该表单已正常提交(没有 ajax)。

1) 扩展 JIRA.FormDialog

我的第一种方法是扩展JIRA.FormDialog组件以发送FormData带有文件和其他表单输入的对象。这有效,服务器收到了multipart/form-data请求。

(编辑) 问题是将响应返回到对话框。我找不到办法做到这一点。响应总是返回带有页眉和页脚的完整 JIRA 页面,因为不知何故服务器不知道我在对话框的上下文中。

我找出问题所在。服务器不使用参数inlinedecorator位置(附加到 FormData 对象)。我尝试将这些参数添加到操作 url 并且它有效:

   <form ... action="MyUploadAction.jspa#if($action.isInlineDialogMode())?inline=true&decorator=dialog#end"> 

这是代码:

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"
    }
});

2) 文件读取器 API

接下来我尝试了FileReaderAPI。当用户更改文件输入时,我读取文件并将其内容存储在 DOM 中。当通过 ajax 提交表单时,文件内容被视为普通 var。我不太喜欢这种方法,因为如果文件很大,那么网页会占用这个不必要的内存来存储内容。

3) JIRA 临时文件 API

最后,当您在输入中输入文件时,我尝试使用 JIRA 方法(删除ignore-inline-attach)发送文件。JIRA 将它们作为临时文件存储在服务器中。然后,您必须通过 JIRA Attachment API 在 webwork 操作中访问它们。这种方法的缺点是可以发送多个文件,但我只想发送一个文件(就像你一样)。

请注意,最后两种方法需要两种方法来处理服务器中的文件:1)正常MultiPartRequestWrapper,因为用户仍然可以在新页面中打开对话框并且表单不是通过 ajax 提交的。2)具体的方法。

在解决了响应问题(如上所述)之后,我最终使用了 1) 方法。高温高压

于 2013-12-11T18:47:01.920 回答