簡體   English   中英

如何防止某人在Vaadin 8中快速單擊FileDownloader按鈕?

[英]How to prevent someone from rapid clicking on a FileDownloader button in Vaadin 8?

使用Vaadin手冊中的代碼,我們可以:

Button downloadButton = new Button("Download image");
FileDownloader fileDownloader = new FileDownloader(createResource());
fileDownloader.extend(downloadButton);

此示例代碼的問題在於,有人可能會不停地快速單擊downloadButton ,並且動態創建的文件將以用戶單擊的速度生成。 有沒有辦法放置一個限制器,即在x次之后阻止用戶下載? 另外,如果您快速單擊此按鈕,則會收到錯誤,特別是DefaultErrorHandler

至少我希望有一種方法可以防止某人下載文件超過x次。 最好也有類似downloadButton.disableOnClick()這樣的東西,但我似乎找不到下載完成后重新啟用的方法,因為沒有鈎子可以在下載完成時通知您,但主要目標是阻止某人連續下載50倍。

為了這:

但我似乎找不到下載完成后重新啟用的方法,因為沒有鈎子會在下載完成時通知您

不,據我所知,沒有鈎子可以從客戶端獲得瀏覽器的下載功能,以告知Vaadin何時下載就緒。

但是,這可能是服務器端的解決方案。

我相信您可以從StreamResource創建Resource並在后者中實現:

@Override
public InputStream getStream() {
    return s;
}

下載可以考慮當流准備s被關閉。 但是, InputStream.close()也沒有任何鈎子。 為此,您可以為InputStream實現包裝器實現,例如:

@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();
    }
}

使用這種包裝器,您可以借助回調函數獲得通知,然后該回調函數將處理您決定實現的任何按鈕邏輯。

最終,你的sgetStream()會是這樣:

new CloseNotifyingInputStream(getTheActualInputStream(),
            cnis -> log.info("Handling the btn logic")
);

`

這是一種在下載50次后禁用按鈕的解決方案。 我將按鈕添加為createResource的參數。 如果它將保留在同一類中,則不一定需要該參數。

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,但語法似乎沒有改變。

Viritin(Vaadin附加組件)DownloadButton現在支持將內容發送到客戶端時執行的邏輯。 要顯示這些內容,您需要啟用“推送”功能或向用戶界面添加輪詢間隔。

請參閱項目測試源中的示例代碼。 它使用Button的disableOnClick功能,但是一旦將內容寫入瀏覽器,便重新啟用該按鈕:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM