Иногда ресурс StreamResource не обнаруживается при нажатии кнопки загрузки в закрывающемся диалоговом окне. - PullRequest
2 голосов
/ 14 марта 2019

Я работаю над диалоговым окном, в котором есть ссылка для загрузки динамически сгенерированного файла через 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% времени, но второй фрагмент кода, кажется, почему?

1 Ответ

1 голос
/ 15 марта 2019

За кулисами StreamResource работает так, что генерирует временный URL и добавляет экземпляр ресурса на карту с URL в качестве ключа.Затем он используется для поиска нужного материала для добавления в ответ, когда браузер делает запрос на этот URL.

Чтобы предотвратить бесконечную утечку памяти, он реализован так, что ресурс удаляется из этого глобальногоКарта немедленно, когда компонент "владелец" отсоединен.В вашем случае anchor является владельцем, и он действительно отсоединен, когда диалог закрыт.Наблюдаемая вами случайность зависит от того, какой запрос первым достигает сервера.

...