如何将 Wicket 的 DownloadLink 与动态生成的文件一起使用?

2022-09-02 13:02:31

DownloadLink对于创建用于下载文件的按钮/链接非常有用,如下所示:

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

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

但是,我想触发仅在单击按钮/链接时下载的文件的生成。换句话说,在单击时,我会调用一个生成文件的方法(在本例中为Pentaho报告),将其放在临时位置并返回指向它。然后我会告诉使用它。问题是,这在某种程度上是可能的吗FileDownloadLinkFile

目前,我们有类似于下面的代码的东西,它可以工作,但我对是否可以使用感兴趣。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"));
  }
});

(Wicket 1.4.18,如果它有所作为的话。


答案 1

您不能使用采用 as 参数的构造函数吗?并使生成在其 .A 是一个不错的选择,因为 ,因此文件生成将只调用一次。ModelModelFilegetObject()LoadableDetachableModelload()

如果每次单击链接时都要重新生成文件,请使用 DownloadLink.setDeleteAfterDownload(true) 来确保文件在提供后自动删除。

我没有使用1.4,但是1.3中的源代码显示,是通过在.FilegetModelObject()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 代替。