在关闭对话框中单击下载按钮时有时找不到 StreamResource 资源 window
StreamResource sometimes resource not found when clicking download button in a closing dialog window
我正在开发一个对话框,其中下载了 link 动态生成的文件
通过 StreamResource,当用户点击下载按钮时,对话框应该关闭。
很简单。但是,当用户打开对话框并单击下载按钮时 有时 创建的文件会成功下载。问题是在其他时候,用户在尝试下载创建的文件时可能会随机遇到 "resource/file not found" 错误消息。下面是重现问题的代码片段。
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 作为键的映射中。然后,当浏览器向 URL.
发出请求时,这将用于查找要放入响应中的正确内容
为了防止这种情况无限期地泄漏内存,实现后,当“所有者”组件分离时,资源会立即从该全局映射中删除。在您的情况下, anchor
是所有者,当对话框关闭时它确实是分离的。您观察到的随机性取决于哪个请求最先到达服务器。
因此,锚点不应该出现在对话框中,而是例如作为视图本身的不可见组件,您可以在按钮单击事件中触发它。 Gist 中有一个完整的代码示例:
https://gist.github.com/TatuLund/0a0e7bdc1d182394c99fe2adfa3e7c6e
我正在开发一个对话框,其中下载了 link 动态生成的文件 通过 StreamResource,当用户点击下载按钮时,对话框应该关闭。 很简单。但是,当用户打开对话框并单击下载按钮时 有时 创建的文件会成功下载。问题是在其他时候,用户在尝试下载创建的文件时可能会随机遇到 "resource/file not found" 错误消息。下面是重现问题的代码片段。
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 作为键的映射中。然后,当浏览器向 URL.
为了防止这种情况无限期地泄漏内存,实现后,当“所有者”组件分离时,资源会立即从该全局映射中删除。在您的情况下, anchor
是所有者,当对话框关闭时它确实是分离的。您观察到的随机性取决于哪个请求最先到达服务器。
因此,锚点不应该出现在对话框中,而是例如作为视图本身的不可见组件,您可以在按钮单击事件中触发它。 Gist 中有一个完整的代码示例:
https://gist.github.com/TatuLund/0a0e7bdc1d182394c99fe2adfa3e7c6e