GWT中存在许多难以解决的问题:
FormDataGWT中没有对象,因此您必须使用JSNI来获取一个.RequestBuilder不支持发送FormaData但只支持字符串.RequestBuilder 不支持上传或下载进度通知.FileUpload 不支持multiple属性.幸运的是,gwtquery 1.0.0具有一系列有助于解决问题的功能.
这里有一个工作示例(只有很少的代码行),适用于支持HTML5文件api的所有浏览器:
import static com.google.gwt.query.client.GQuery.*;
[...]
final FileUpload fileUpload = new FileUpload();
RootPanel.get().add(fileUpload);
$(fileUpload)
// FileUpload does not have a way to set the multiple attribute,
// we use gQuery instead
.prop("multiple", true)
// We use gQuery events mechanism
.on("change", new Function() {
public void f() {
// Use gQuery utils to create a FormData object instead of JSNI
JavaScriptObject form = JsUtils.runJavascriptFunction(window, "eval", "new FormData()");
// Get an array with the files selected
JsArray<JavaScriptObject> files = $(fileUpload).prop("files");
// Add each file to the FormData
for (int i = 0, l = files.length(); i < l; i++) {
JsUtils.runJavascriptFunction(form, "append", "file-" + i, files.get(i));
}
// Use gQuery ajax instead of RequestBuilder because it
// supports FormData and progress
Ajax.ajax(Ajax.createSettings()
.setUrl(url)
.setData((Properties)form))
// gQuery ajax returns a promise, making the code more declarative
.progress(new Function() {
public void f() {
double total = arguments(0);
double done = arguments(1);
double percent = arguments(2);
// Here you can update your progress bar
console.log("Uploaded " + done + "/" + total + " (" + percent + "%)");
}
})
.done(new Function() {
public void f() {
console.log("Files uploaded, server response is: " + arguments(0));
}
})
.fail(new Function() {
public void f() {
console.log("Something went wrong: " + arguments(0));
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
另一个选择是使用gwtupload,它支持任何浏览器,它带有一些不错的小部件和进度条,甚至你可以插入自己的进度和状态小部件.
它不使用HTML5 File api,而是基于服务器监听器的ajax解决方案.但是,它将在未来版本中支持html5,回归旧浏览器的ajax机制.当gwtupload支持此功能时,您不必修改代码中的任何内容.