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

Jon*_*nik 18 java wicket download

DownloadLink 使用以下行创建用于下载文件的按钮/链接非常方便:

add(new DownloadLink("downloadButton", getReportFile(), "report.pdf"));
Run Code Online (Sandbox Code Playgroud)

<input type="button" wicket:id="downloadButton" value="Download" />
Run Code Online (Sandbox Code Playgroud)

但是,我想仅在单击按钮/链接时触发生成文件才能下载.换句话说,点击后,我会调用一个生成文件的方法(在我们的例子中是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"));
  }
});
Run Code Online (Sandbox Code Playgroud)

(Wicket 1.4.18,如果它有所作为.)

Xav*_*ica 15

你不能使用带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");
Run Code Online (Sandbox Code Playgroud)

源代码 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 */...);
}
Run Code Online (Sandbox Code Playgroud)

  • 1.改为使用`LoadableDetachableModel`.在请求期间可能会多次调用`getObject()`,但`load()`不会; 2.如果文件总是重新生成,你可以调用`downloadLink.setDeleteAfterDownload(true)`,这样你就不用担心以后删除临时文件了. (4认同)
  • 您可能需要在`DownloadLink`上调用`setCacheDuration(Duration.NONE)`来强制浏览器重新请求文件,从而重新生成对象. (3认同)
  • 您还可以覆盖DownloadLink的onClick并在调用super方法之前执行`setModelObject()`.不过,哈维的建议更加清晰. (2认同)

mar*_*n-g 11

请改用org.apache.wicket.markup.html.link.ResourceLink.