Подтвердить что ты не робот

Как использовать Wicket DownloadLink с файлом, созданным на лету?

DownloadLink является приятным и удобным для создания кнопки/ссылки для загрузки файла в следующих строках:

add(new DownloadLink("downloadButton", getReportFile(), "report.pdf"));

и

<input type="button" wicket:id="downloadButton" value="Download" />

Однако я бы хотел, чтобы запускал генерацию файла для загрузки только при нажатии кнопки/ссылки. Другими словами, после щелчка я вызываю метод, который генерирует файл (отчет Pentaho в нашем случае), помещает его в временное место и возвращает на него File. Тогда я бы сказал DownloadLink использовать File. Вопрос в том, это возможно как-то?

В настоящее время мы имеем что-то вроде кода ниже, который работает, но меня интересует, можно ли использовать DownloadLink.

add(new Link<Void>("downloadButton") {
  @Override
  public void onClick() {
    IResourceStream resourceStream = new AbstractResourceStreamWriter() {
      @Override 
      public void write(OutputStream output) {
        try {
          reportService.generateReport(output, report);
        } catch (IOException e) {
          // ...
        }
      }

      @Override
      public String getContentType() {                        
        return CONTENT_TYPE_PDF;
      }
    };

    getRequestCycle()
      .setRequestTarget(new ResourceStreamRequestTarget(resourceStream)
      .setFileName("report.pdf"));
  }
});

(Калитка 1.4.18, если это имеет значение.)

4b9b3361

Ответ 1

Не можете ли вы использовать конструктор, который принимает аргумент Model? И сделайте Model сгенерируйте File в getObject(). A LoadableDetachableModel является хорошим выбором, учитывая, что load() и, следовательно, генерация файлов, будут вызываться только один раз.

Если файл должен быть свежеприготовлен при каждом нажатии ссылки, используйте DownloadLink.setDeleteAfterDownload(true), чтобы гарантировать, что файл будет автоматически удален после его обслуживается.

Я не использую 1.4, но исходный код в 1.3 показывает, что File извлекается с помощью getModelObject() в методе onClick() Link.

IModel fileModel = new AbstractReadOnlyModel(){
    public Object getObject() { 
        return generateFile();
    }
};

DownloadLink link = new DownloadLink(linkId, fileModel, "report.pdf");

Исходный код DownloadLink.onClick()

public void onClick()
{
    final File file = (File)getModelObject();
            ...
    IResourceStream resourceStream = new FileResourceStream(
            new org.apache.wicket.util.file.File(file));
    getRequestCycle().setRequestTarget(.../* uses resourceStream */...);
}

Ответ 2

Вместо этого используйте org.apache.wicket.markup.html.link.ResourceLink.