【问题标题】:How to handle drag & drop upload of folders?如何处理文件夹的拖放上传?
【发布时间】:2017-04-01 03:19:51
【问题描述】:

我正在使用拖放的 Vaadin Web 应用程序中实现上传功能,例如 Vaadin sampler example

我的代码与那里的示例代码几乎相同。但是,在尝试我的代码和链接示例时,有一个重要区别:删除文件夹时,我的代码开始显示进度微调器,但永远不会结束。从未调用过任何StreamVariable 回调方法。实际上没有上传任何字节。 示例应用程序什么都不做(至少用户可见)。

实际上我什至不希望用户能够上传文件夹,但我需要能够检测拖放的“文件”是否是文件夹。

不幸的是,我得到的 WrapperTransferableHtml5File 对象都没有给我任何指示。我只是想出启发式方法来确定我是否有文件或文件夹:检查 MIME 类型是否为空,检查文件大小是否很小,检查文件名中是否没有点。不过,这些都不是很安全。

如何检测和防止尝试上传文件夹?

这是我的代码(同样,几乎是链接的 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();
    }
}

【问题讨论】:

  • 你应该包含你的代码。
  • 既然没有获取到文件路径,那么获取文件ext和文件名。如果是这样,文件夹没有分机。所以你应该检查文件名是否有“.*”。如果文件夹没有 .abc,那么您应该使用该事件。
  • 如上所述,我已经想到了这一点,但这不是一个安全的启发式方法,因为允许文件夹名称中包含点。此外,某些文件中根本没有点。我的申请甚至可能会收到其中的一些。

标签: java vaadin vaadin7


【解决方案1】:

此问题已在 Vaadin 7.7.0 中出现fixed

这是对应的change注:

大多数浏览器不支持文件夹上传,可能会导致 StreamVariable 方法不会在某些配置上触发。 此修复尝试检测并阻止上传文件夹。

【讨论】:

    猜你喜欢
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 2012-12-12
    • 2012-01-27
    • 2013-01-27
    相关资源
    最近更新 更多