我正在开发一个对话框,其中包含指向动态生成文件的下载链接 通过 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());
}
因此用户有时可能会在点击下载时遇到资源未找到的错误消息。
"Resource is not found for path" image
有趣的是,如果我在 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% 有效,但第二个代码片段似乎有效,为什么?
最佳答案
在幕后,StreamResource
会生成一个临时 URL 并将资源实例添加到以 URL 作为键的 map 中。然后,当浏览器向该 URL 发出请求时,这将用于查找要放入响应中的正确内容。
为了防止这种情况无限期地泄漏内存,它的实现是为了在“所有者”组件分离时立即从该全局映射中删除资源。在您的情况下, anchor
是所有者,当对话框关闭时它确实是分离的。您观察到的随机性取决于哪个请求最先到达服务器。
因此, anchor 不应该在对话框中,而是例如作为 View 本身的不可见组件,您在按钮单击事件中触发它。这里有 Gist 中的完整代码示例:
https://gist.github.com/TatuLund/0a0e7bdc1d182394c99fe2adfa3e7c6e
关于java - 在关闭对话框窗口中单击下载按钮时,有时找不到 StreamResource 资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55163889/