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

19.4k Views Asked by At

In PrimeFaces 8.0 the DefaultStreamedContent cannot be initialized like new DefaultStreamedContent(inputStream, contentType, name) because it has been deprecated, instead you shound use DefaultStreamedContent.builder().

Although while doing .stream() it asks for a SerializableSupplier<InputStream> instead of an InputStream like in the version before 8.0.

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

How can I convert a InputStream to a SerializableSupplier?

4

There are 4 best solutions below

3
On BEST ANSWER

Everthing is in the migration guide here: https://github.com/primefaces/primefaces/wiki/Migration-Guide.

in general the following will work:

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

But the idea behind the change is a different.
If you use a RequestScoped bean to build the StreamedContent, your bean and therefore the StreamedContent will be created twice:

  1. when rendering the view
  2. when streaming the resource (this is a new browser request!)

In this case, your is will probably created 2 times. Most of the times this results in 1 useless IO access or DB call.

To only create the is one time, you should lazy initialize it via the supplier lambda:

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

For MySQL stored image I use this:

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();
0
On

The lazy initialize answer above by @tandraschko did not work for me in Netbeans using java 8. I had to have the FileInputStream created before injecting it into the builder.

So my code looks like :

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

Thought I would comment just in case someone else was running into compiling issues.

1
On

This worked for me

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();