javascript中的多部分表单数据与使用FileUpload的java服务器

时间:2013-02-19 09:59:27

标签: java file-upload multipartform-data apache-commons-fileupload

我尝试仅使用javascript发送带有文件的多部分表单数据。我自己写了这个请求。所以我的javascript代码如下:

var data =
    '------------f8n51w2QYCsvNftihodgfJ\n' +
    'Content-Disposition: form-data; name="upload-id"\n' +
    '\n' +
    'uploadedFiles\n' +
    '------------f8n51w2QYCsvNftihodgfJ\n' +
    'Content-Disposition: form-data; name="file"; filename="doc1.txt"\n' +
    'Content-Type: text/plain\n' +
    '\n' +
    'azerty\n' +
    '------------f8n51w2QYCsvNftihodgfJ--\n';

    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload');
    xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=----------f8n51w2QYCsvNftihodgfJ');
    xhr.sendAsBinary(data);

我在Firefox 18上运行此javascript。 所以我在/upload上获得了一个servlet。这是代码:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    RequestContext request_context = new ServletRequestContext(request);
    boolean is_multipart = ServletFileUpload.isMultipartContent(request_context);
    if (is_multipart) {
        FileUpload file_upload = new FileUpload(fileItemFactory);
        List<FileItem> file_items = file_upload.parseRequest(request_context); // This line crash
    }
}

正如评论所说,行file_upload.parseRequest(request_context);崩溃并抛出以下异常:

org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    at org.apache.commons.fileupload.MultipartStream.readHeaders(MultipartStream.java:539)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:976)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:942)
    at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:349)

我只是不知道为什么我得到了这个例外......有什么想法吗?

似乎MultipartStream无法找到请求标头。但是,如果我记录标题,它们都在这里,它们是正确的。

我的servlet代码使用“普通”形式。我试着记录一个普通形式的请求体和标题,它们是相同的(当然除了边界)。

我还尝试使用无效内容更改data变量。错误仍然是一样的,所以我的标题肯定存在问题,但我看不出是什么。

3 个答案:

答案 0 :(得分:2)

我找到了解决方案。

\n 不是多部分表单的有效分隔符。您必须使用\r\n。现在我的代码工作正常。

答案 1 :(得分:0)

我不明白为什么你使用sendAsBinary。如果不是绝对必要,我不会自己组装有效负载(data变量),但使用FormData

https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/FormData/Using_FormData_Objects

var oMyForm = new FormData();

oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // number 123456 is immediately converted to string "123456"

// HTML file input user's choice...
oMyForm.append("userfile", fileInputElement.files[0]);

// JavaScript file-like object...
var oFileBody = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var oBlob = new Blob([oFileBody], { type: "text/xml"});

oMyForm.append("webmasterfile", oBlob);

var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);

答案 2 :(得分:0)

尝试将 f8n51w2QYCsvNftihodgfJ 更改为 f8n51w2QYCsvNftihodgfM

我尝试使用不同的随机边界运行代码,结果只有 f8n51w2QYCsvNftihodgfJ \ n 出现问题。我估计你可以尝试不同的边界,因为它实际上只是一个随机字符串。