PrimeFaces 8.0 DefaultStreamedContent.builder().stream() 要求 SerializableSupplier<InputStream>

PrimeFaces 8.0 DefaultStreamedContent.builder().stream() asks for SerializableSupplier<InputStream>

在 PrimeFaces 8.0 中,DefaultStreamedContent 不能像 new DefaultStreamedContent(inputStream, contentType, name) 那样初始化,因为它已被弃用,您应该使用 DefaultStreamedContent.builder().

尽管在执行 .stream() 时它要求 SerializableSupplier<InputStream> 而不是 8.0 之前版本中的 InputStream

DefaultStreamedContent.builder().contentType(contentType).name(name).stream(is).build();
                                                                            ^^

如何将 InputStream 转换为 SerializableSupplier

一切都在迁移指南中:https://github.com/primefaces/primefaces/wiki/Migration-Guide

一般来说,以下内容会起作用:

DefaultStreamedContent.builder().contentType(contentType).name(name).stream(() -> is).build();

但改变背后的想法是不同的。
如果您使用 RequestScoped bean 构建 StreamedContent,则您的 bean 和 StreamedContent 将被创建两次:

  1. 渲染视图时
  2. 流式传输资源时(这是一个新的浏览器请求!)

在这种情况下,您的 is 可能会创建 2 次。大多数情况下,这会导致 1 次无用的 IO 访问或数据库调用。

要只创建一次 is,您应该通过供应商 lambda 延迟初始化它:

DefaultStreamedContent.builder().contentType(contentType).name(name).stream(() -> new FileInputStream(....)).build();

这对我有用

DataHandler dataHandler = someBean.getFileData();
byte contents[] = IOUtils.toByteArray(dataHandler.getInputStream());
StreamedContent streamedContent = DefaultStreamedContent.builder()
                    .name(someBean.getFileName())
                    .contentType("application/octet-stream")
                    .stream(() -> new ByteArrayInputStream(contents)).build();

对于 MySQL 存储的图像,我使用这个:

resultset = statement.executeQuery("call sp_query()");
if(resultset.next()) {

    new DefaultStreamedContent();
    StreamedContent photo = DefaultStreamedContent.builder().contentType("contentType").name("name").stream(() -> resultset.getBinaryStream("picture")).build());
}

// Close the connection
con.close();

@tandraschko 上面的惰性初始化答案在使用 java 8 的 Netbeans 中对我不起作用。我必须在将其注入构建器之前创建 FileInputStream。

所以我的代码看起来像:

public StreamedContent getFiledownload() {
        FileInputStream fis = new FileInputStream("...");
        filedownload = DefaultStreamedContent.builder()
                .contentType("...")
                .name("...")
                .stream(() -> fis)
                .build();
        return filedownload;
    }

以为我会发表评论,以防其他人 运行 陷入编译问题。