2

StreamResource を介して動的に生成されたファイルへのダウンロード リンクを持つダイアログに取り組んでおり、ユーザーがダウンロード ボタンをクリックすると、ダイアログが閉じます。十分に単純です。ただし、ユーザーがダイアログを開いてダウンロード ボタンをクリックする、作成されたファイルが正常にダウンロードされることがあります。問題は、作成されたファイルをダウンロードしようとすると、「リソース/ファイルが見つかりません」というエラー メッセージがランダムに表示される場合があることです。問題を再現するコード スニペットの下。

public class HomeView extends VerticalLayout{

Dialog dialog;

public HomeView() {
    //Set up dialog
    dialog = new Dialog();
    Button downloadButton = new Button("Download");
    //This might be the problem. Dialog might be closed before the download even starts?
    downloadButton.addClickListener(click -> dialog.close());
    Anchor anchor = new Anchor();
    anchor.add(downloadButton);
    anchor.setHref(new StreamResource("file", () -> createInputStream()));
    dialog.add(anchor);

    //Add a button to open dialog
    Button openDialog = new Button("Open Dialog");
    openDialog.addClickListener(click -> dialog.open());
    add(openDialog);
}

private InputStream createInputStream() {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
        outputStream.write("text".getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new ByteArrayInputStream(outputStream.toByteArray());
}

そのため、ダウンロードを押すと、リソースが見つからないというエラー メッセージが表示されることがあります。

「パスのリソースが見つかりません」の画像

面白いことに、createInputStream() メソッドでダイアログを閉じると、エラー メッセージが表示されません。以下に例を示します。

public class HomeView extends VerticalLayout{

Dialog dialog;

public HomeView() {
    dialog = new Dialog();
    Button downloadButton = new Button("Download");
    //Commented out
    //downloadButton.addClickListener(click -> dialog.close());
    Anchor anchor = new Anchor();
    anchor.add(downloadButton);
    anchor.setHref(new StreamResource("file", () -> createInputStream()));
    dialog.add(anchor);

    Button openDialog = new Button("Open Dialog");
    openDialog.addClickListener(click -> dialog.open());
    add(openDialog);
}

private InputStream createInputStream() {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
        outputStream.write("text".getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }
    //Close the dialog here
    dialog.close();
    return new ByteArrayInputStream(outputStream.toByteArray());
}

ダウンロード ボタンを何度クリックしても、リソース エラー メッセージが表示されず、ダイアログが意図したとおりに閉じます。

Vaadin 13.0.1 を使用しています。

ということで、最後にこんな質問を。 最初のコード スニペットは常に 100% 機能するわけではありませんが、2 番目のコード スニペットは機能するようです。なぜでしょうか?

4

1 に答える 1