Как использовать Wicket DownloadLink с файлом, сгенерированным на лету? - PullRequest
18 голосов
/ 04 октября 2011

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, если онаимеет значение.)

Ответы [ 2 ]

15 голосов
/ 04 октября 2011

Разве вы не можете использовать конструктор, который принимает Model в качестве аргумента? И заставить Model сгенерировать File в его getObject(). 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 */...);
}
11 голосов
/ 04 октября 2011

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

...