1

我正在尝试使用 Play Framework 2 (Java) 实现文件上传

为此,我遵循了以下指南:http ://www.playframework.org/documentation/2.0/JavaFileUpload

在服务器端,我总是在 MultipartFormData 中获得 MissingFilePart 对象。

这是我的看法:

@form(action = routes.ImmediateCollections.savePoliceReport, 'enctype -> "multipart/form-data") {
    <fieldset>
        <div class="fileupload fileupload-new">
            <span class="btn btn-file">
                <span class="fileupload-new">Select file</span>
                <span class="fileupload-exists">Change</span>
                <input type="file" name="policeReportFile" id="policeReportFile"/>
            </span>
            <span class="fileupload-preview"></span>
            <a href="#" class="close fileupload-exists" style="float: none">×</a>
        </div>
    </fieldset>
    @controls {
        @submitbutton()
    }
}

这会生成以下 html:

<form action="/immediatecollections/save-policereport" method="POST" enctype="multipart/form-data">
    <fieldset>
        <div class="fileupload fileupload-new">
            <span class="btn btn-file">
                <span class="fileupload-new">Select file</span>
                <span class="fileupload-exists">Change</span>
                <input type="file" name="policeReportFile" id="policeReportFile">
            </span>
            <span class="fileupload-preview"></span>
            <a href="#" class="close fileupload-exists" style="float: none">×</a>
        </div>
    </fieldset>
    <div class="control-group">
        <div class="controls">
            <input type="submit" class="btn btn-success" value="Save">
        </div>
    </div>
</form>

(对于那些想知道跨度和 div 的人,我正在使用优秀的jasny 引导扩展。)

请注意,我只有一个输入字段。此表单仅用于一个目的:上传 1 个文件。

这是我的控制器:

public static Result savePoliceReport() {
    Http.MultipartFormData formData = request().body().asMultipartFormData();
    Http.MultipartFormData.FilePart policeReportFile = formData.getFile("policeReportFile");
    if (policeReportFile != null) {
        // move file to somewhere
        // save metadata to database

        // for simplicity's sake: return json success = true or false
        ObjectNode jsonResult = Json.newObject();
        jsonResult.put("success", true);
        return ok(jsonResult);
    } else {
        ObjectNode jsonResult = Json.newObject();
        jsonResult.put("success", false);
        return badRequest(jsonResult);
    }
}

这个方法在路由文件中是这样定义的:

POST    /immediatecollections/save-policereport     controllers.ImmediateCollections.savePoliceReport

现在,当我在服务器端上传文件并进行调试时,这就是我得到的请求:

服务器端调试

如果我没看错,说明文件内容丢失。发生了什么?字节在传输中丢失了吗?如果发生故障,为什么 Play 不抛出异常?

我在 Chrome 和 Internet Explorer 中都试过了,两次结果都一样。

我究竟做错了什么?谢谢!

4

2 回答 2

1

这最终在谷歌群组上得到解决,我将从那里重新发布答案:

詹姆斯·罗珀:

当多部分数据中的文件名字段为空时抛出 MissingFilePart(名称有点误导)。为什么浏览器会发送一个空文件名,这是一个有趣的问题。在 Chrome 开发工具的 Network 选项卡中,您可以上传一个小的(只有几个字节)文件,然后查看请求正文吗?您可以在这里发布请求正文吗?它应该看起来像这样:

--AaB03x 内容配置:表单数据;名称="图片"; filename="file1.txt" 内容类型:文本/纯文本

这是上传文件的内容--AaB03x--

这里的另一个问题是,虽然 HTML 规范鼓励客户端尽最大努力提交文件名参数,但它不是强制性字段,所以如果它不存在,Play 应该不会失败。

我的回复:

你是对的,文件名丢失了。事实证明,Jasny 的 javascript 以某种方式破坏了输入元素。由于时间不够,我只是用一个没有花哨标记的基本元素替换了它,也许我稍后会回到这个问题。如果有人想出一个解决方案,我会很高兴听到它,但现在我会保持原样。

感谢您的回复詹姆斯,我要花更长的时间才能找到那个错误。:-)

TLDR:输入标签中缺少名称属性

于 2013-02-27T15:38:02.440 回答
0

听起来很奇怪,示例:http ://www.playframework.com/documentation/2.0/JavaFileUpload 是否 也以同样的方式失败?

于 2013-02-27T13:37:20.917 回答