如何处理文件夹的拖放上传?
How to handle drag & drop upload of folders?
我正在我的 Vaadin Web 应用程序中实现一个使用拖放的上传功能,就像这个 Vaadin sampler example。
我的代码与那里的示例代码几乎相同。但是,在尝试我的代码和链接示例时,有一个重要区别:删除文件夹时,我的代码开始显示进度微调器,但从未完成。 None 的 StreamVariable
回调方法被调用过。实际上没有上传任何字节。
示例应用程序什么都不做(至少用户可见)。
实际上我什至不希望用户能够上传文件夹,但我需要能够检测拖放的 "file" 是否是一个文件夹。
不幸的是,我得到的 WrapperTransferable
和 Html5File
对象都没有给我任何指示。我只是想出启发式方法来确定我是否有文件或文件夹:检查 MIME 类型是否为空,检查文件大小是否很小,检查文件名中是否有点。 None 其中非常安全。
我如何检测并阻止尝试上传文件夹?
这是我的代码(同样,几乎是链接 Vaadin 示例的直接副本)。
public class AttachmentDropBox extends DragAndDropWrapper implements DropHandler {
private final ProgressBar progress;
public AttachmentDropBox(Component root, ProgressBar progress) {
super(root);
this.progress = progress;
progress.setIndeterminate(true);
setDropHandler(this);
}
@Override
public void drop(DragAndDropEvent dropEvent) {
// expecting this to be an html5 drag
if (!(dropEvent.getTransferable() instanceof WrapperTransferable)) {
return;
}
final WrapperTransferable tr = (WrapperTransferable) dropEvent.getTransferable();
final Html5File[] files = tr.getFiles();
if (files == null) {
return;
}
if (files.length != 1) {
Notification.show("Please upload single files only", Notification.Type.WARNING_MESSAGE);
return;
}
Html5File file = files[0];
if (file.getFileSize() > settings.getClientMaxAttachmentSize()) {
Notification.show(
MessageFormat.format("File rejected. Attachments may not exceed {0} in size.",
FileUtils.byteCountToDisplaySize(settings.getClientMaxAttachmentSize())),
Notification.Type.WARNING_MESSAGE);
return;
}
final ByteArrayOutputStream bas = new ByteArrayOutputStream();
final StreamVariable streamVariable = new StreamVariable() {
@Override
public OutputStream getOutputStream() {
return bas;
}
@Override
public boolean listenProgress() {
return false;
}
@Override
public void onProgress(final StreamingProgressEvent event) {
// not called
}
@Override
public void streamingStarted(final StreamingStartEvent event) {
LOG.info("Upload started: " + event.getFileName());
}
@Override
public void streamingFinished(final StreamingEndEvent event) {
progress.setVisible(false);
LOG.info("Upload finished: " + event.getFileName());
}
@Override
public void streamingFailed(final StreamingErrorEvent event) {
Notification.show(
MessageFormat.format("Failed to upload file: {0}",
StringUtils.abbreviate(event.getException().getMessage(), 100)),
Notification.Type.ERROR_MESSAGE);
LOG.error("Failed to upload file '{}'", event.getFileName(), event.getException());
progress.setVisible(false);
}
@Override
public boolean isInterrupted() {
return false;
}
};
file.setStreamVariable(streamVariable);
progress.setVisible(true);
}
@Override
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
}
我正在我的 Vaadin Web 应用程序中实现一个使用拖放的上传功能,就像这个 Vaadin sampler example。
我的代码与那里的示例代码几乎相同。但是,在尝试我的代码和链接示例时,有一个重要区别:删除文件夹时,我的代码开始显示进度微调器,但从未完成。 None 的 StreamVariable
回调方法被调用过。实际上没有上传任何字节。
示例应用程序什么都不做(至少用户可见)。
实际上我什至不希望用户能够上传文件夹,但我需要能够检测拖放的 "file" 是否是一个文件夹。
不幸的是,我得到的 WrapperTransferable
和 Html5File
对象都没有给我任何指示。我只是想出启发式方法来确定我是否有文件或文件夹:检查 MIME 类型是否为空,检查文件大小是否很小,检查文件名中是否有点。 None 其中非常安全。
我如何检测并阻止尝试上传文件夹?
这是我的代码(同样,几乎是链接 Vaadin 示例的直接副本)。
public class AttachmentDropBox extends DragAndDropWrapper implements DropHandler {
private final ProgressBar progress;
public AttachmentDropBox(Component root, ProgressBar progress) {
super(root);
this.progress = progress;
progress.setIndeterminate(true);
setDropHandler(this);
}
@Override
public void drop(DragAndDropEvent dropEvent) {
// expecting this to be an html5 drag
if (!(dropEvent.getTransferable() instanceof WrapperTransferable)) {
return;
}
final WrapperTransferable tr = (WrapperTransferable) dropEvent.getTransferable();
final Html5File[] files = tr.getFiles();
if (files == null) {
return;
}
if (files.length != 1) {
Notification.show("Please upload single files only", Notification.Type.WARNING_MESSAGE);
return;
}
Html5File file = files[0];
if (file.getFileSize() > settings.getClientMaxAttachmentSize()) {
Notification.show(
MessageFormat.format("File rejected. Attachments may not exceed {0} in size.",
FileUtils.byteCountToDisplaySize(settings.getClientMaxAttachmentSize())),
Notification.Type.WARNING_MESSAGE);
return;
}
final ByteArrayOutputStream bas = new ByteArrayOutputStream();
final StreamVariable streamVariable = new StreamVariable() {
@Override
public OutputStream getOutputStream() {
return bas;
}
@Override
public boolean listenProgress() {
return false;
}
@Override
public void onProgress(final StreamingProgressEvent event) {
// not called
}
@Override
public void streamingStarted(final StreamingStartEvent event) {
LOG.info("Upload started: " + event.getFileName());
}
@Override
public void streamingFinished(final StreamingEndEvent event) {
progress.setVisible(false);
LOG.info("Upload finished: " + event.getFileName());
}
@Override
public void streamingFailed(final StreamingErrorEvent event) {
Notification.show(
MessageFormat.format("Failed to upload file: {0}",
StringUtils.abbreviate(event.getException().getMessage(), 100)),
Notification.Type.ERROR_MESSAGE);
LOG.error("Failed to upload file '{}'", event.getFileName(), event.getException());
progress.setVisible(false);
}
@Override
public boolean isInterrupted() {
return false;
}
};
file.setStreamVariable(streamVariable);
progress.setVisible(true);
}
@Override
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
}