首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止有人在Vaadin8中快速点击FileDownloader按钮?

如何防止有人在Vaadin8中快速点击FileDownloader按钮?
EN

Stack Overflow用户
提问于 2018-03-02 16:55:47
回答 3查看 560关注 0票数 2

使用我们拥有的Vaadin manual中的代码:

代码语言:javascript
复制
Button downloadButton = new Button("Download image");
FileDownloader fileDownloader = new FileDownloader(createResource());
fileDownloader.extend(downloadButton);

此示例代码的问题在于,有人可以不间断地快速单击downloadButton,并且动态创建的文件将在用户单击时尽快生成。有没有办法设置一个限制器,也就是说在x次之后阻止用户下载?另外,如果你快速点击它,你会得到一个错误,特别是一个DefaultErrorHandler

至少,我希望有一种方法可以防止有人下载文件超过x次。最好也有像downloadButton.disableOnClick()这样的东西,但我似乎找不到一种方法在下载完成后重新启用,因为当下载完成时没有钩子通知你,但主要目标是阻止某人连续下载50x。

EN

回答 3

Stack Overflow用户

发布于 2018-03-02 20:22:35

为此:

但我似乎找不到在下载完成后重新启用的方法,因为当下载完成时没有钩子通知您

不,据我所知,没有钩子来获取浏览器的下载功能,以便在客户端告诉Vaadin何时下载就绪。

然而,这可能是一个服务器端解决方案。

我相信您是从StreamResource创建Resource,并在后者中实现:

代码语言:javascript
复制
@Override
public InputStream getStream() {
    return s;
}

当流s关闭时,可以认为下载已准备就绪。但是InputStream.close()也没有钩子。为此,您可以为InputStream实现包装器实现,如下所示:

代码语言:javascript
复制
@Slf4j
@RequiredArgsConstructor
public class CloseNotifyingInputStream extends InputStream  {

    @FunctionalInterface
    public static interface InputStreamCloseListener {
        public void onInputStreamClose(CloseNotifyingInputStream closeNotifyingInputStream);
    }

    private final InputStream wrappedStream;
    private final InputStreamCloseListener closeListener;

    @Override
    public synchronized int read() throws IOException {
        return wrappedStream.read();
    }

    @Override
    public void close() throws IOException  {
        log.info("Download complete, closing stream");
        closeListener.onInputStreamClose(this);
        wrappedStream.close();          
        super.close();
    }
}

使用这种包装器,您可以在回调函数的帮助下获得通知,然后该回调函数处理您决定实现的任何按钮逻辑。

最终,getStream()中的s将如下所示:

代码语言:javascript
复制
new CloseNotifyingInputStream(getTheActualInputStream(),
            cnis -> log.info("Handling the btn logic")
);

`

票数 3
EN

Stack Overflow用户

发布于 2018-03-02 18:13:01

这是一个解决方案,可以在下载50次后禁用该按钮。我将该按钮作为参数添加到createResource中。如果它停留在同一个类中,则不一定需要该参数。

代码语言:javascript
复制
int downloaded = 0;
private StreamResource createResource(Button downloadButton) {
    return new StreamResource(new StreamSource() {
        @Override
        public InputStream getStream() {
            downloaded++;
            if (downloaded > 50)
            {
                downloadButton.setEnabled(false);
            }
            .. generate your InputStream
        }
    }, "myImage.png");
}

免责声明:我正在使用Vaadin7,但是语法看起来没有改变。

票数 1
EN

Stack Overflow用户

发布于 2018-03-02 21:00:46

Viritin (Vaadin add-on) DownloadButton现在支持在内容发送到客户端时执行逻辑。要显示这些特性,您需要启用推送,或者在UI中添加轮询间隔。

请参阅项目测试源代码中的示例代码。它使用Button中的disableOnClick功能,但在内容写入浏览器后重新启用按钮:

https://github.com/viritin/viritin/blob/master/viritin/src/test/java/org/vaadin/viritin/it/DownloadButtonExample.java

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49065686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档