使用FileDownloader时,lazily detemine文件名

时间:2013-04-04 15:46:49

标签: java download vaadin

在vaadin 7中,使用FileDownloader时如何懒惰地确定文件名?

final Button downloadButton = new Button("Download file");
FileDownloader downloader = new FileDownloader(new StreamResource(new StreamSource() {
    @Override
    public InputStream getStream () {
        return new ByteArrayInputStream(expesiveCalculationOfContent());
    }
}, "file.snub"));

downloader.extend(downloadButton);

在此代码示例中,显然是文件名

  1. 是垃圾
  2. 必须尽早知道。
  3. 如何懒惰地确定下载文件的文件名?

3 个答案:

答案 0 :(得分:9)

我不知道它是否是脏的但是这样做:扩展FileDownloader.handleConnectorRequest()以在调用其super方法之前调用StreamResource.setFilename()。

    {
        final Button downloadButton = new Button("Download file");
        final StreamResource stream = new StreamResource(
                new StreamSource() {
                    @Override
                    public InputStream getStream() {
                        return new ByteArrayInputStream("Hola".getBytes());
                    }
                }, "badname.txt");
        FileDownloader downloader = new FileDownloader(stream) {
            @Override
            public boolean handleConnectorRequest(VaadinRequest request,
                    VaadinResponse response, String path)
                    throws IOException {
                stream.setFilename("better-name.txt");
                return super
                        .handleConnectorRequest(request, response, path);
            }
        };

        downloader.extend(downloadButton);
        layout.addComponent(downloadButton);
    }

答案 1 :(得分:3)

这是我提出的最终解决方案:

/**
 * This specializes {@link FileDownloader} in a way, such that both the file name and content can be determined
 * on-demand, i.e. when the user has clicked the component.
 */
public class OnDemandFileDownloader extends FileDownloader {

  /**
   * Provide both the {@link StreamSource} and the filename in an on-demand way.
   */
  public interface OnDemandStreamResource extends StreamSource {
    String getFilename ();
  }

  private static final long serialVersionUID = 1L;
  private final OnDemandStreamResource onDemandStreamResource;

  public OnDemandFileDownloader (OnDemandStreamResource onDemandStreamResource) {
    super(new StreamResource(onDemandStreamResource, ""));
    this.onDemandStreamResource = checkNotNull(onDemandStreamResource,
      "The given on-demand stream resource may never be null!");
  }

  @Override
  public boolean handleConnectorRequest (VaadinRequest request, VaadinResponse response, String path)
      throws IOException {
    getResource().setFilename(onDemandStreamResource.getFilename());
    return super.handleConnectorRequest(request, response, path);
  }

  private StreamResource getResource () {
    return (StreamResource) this.getResource("dl");
  }

}

答案 2 :(得分:0)

如果假设懒惰地确定文件名意味着动态设置文件名而不管实际文件系统名称是什么,那么下面的代码就是我正在使用的代码。

在下面的代码中,fileName指向本地文件系统文件,其中包含我们要在下载时更改的名称。一个用例就是当一个文件上传到tmp时,文件名包含原始上传中不存在的一些随机字符。

File file = new File(localFile);
final FileResource fileResource = new FileResource(file);
if (!file.exists()) {
   throw new IllegalStateException();
}
final StreamResource stream = new StreamResource(
                            new StreamSource() {
                                @Override
                                public InputStream getStream() {
                                    return fileResource.getStream().getStream();
                                }
                            }, "newname.txt");

FileDownloader fileDownloader = new FileDownloader(stream);
fileDownloader.extend(downloadButton);