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 番目のコード スニペットは機能するようです。なぜでしょうか?