0

I have an InputStream from another server (PDF file from JasperReports) and user is able to download it.

...
VerticalLayout content;
OperationResult<InputStream> jresult;
...
final InputStream ent=jresult.getEntity();
if (ent.available()<=0) return;
Link link = new Link();
link.setCaption("Download the report");
link.setResource(new StreamResource(new StreamSource(){
    private static final long serialVersionUID = 1L;
    @Override
    public InputStream getStream() {
        return ent;
        }
}, "FileName.pdf"));
content.addComponent(link);

If the print server returns the page, "Download the report" will appear and the user can download PDF file by click. But second click on the same link fails. It probably returns empty content. What is wrong? Maybe I must rewind the input stream. How?

Hink
  • 1,054
  • 1
  • 15
  • 31
  • Do you have any stacktrace or its just produces empty content? Also, what is the package of your Link class. – kukis Jun 26 '15 at 09:08

1 Answers1

2

That's because your getStream() method returns the same stream and streams are expected to read from them only once. Once you consume data in the stream, the data is not available anymore.

You may need to firstly convert your InputStream to bytes using this method (taken from this SO question)

public static byte[] readFully(InputStream stream) throws IOException
{
    byte[] buffer = new byte[8192];
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    int bytesRead;
    while ((bytesRead = stream.read(buffer)) != -1)
    {
        baos.write(buffer, 0, bytesRead);
    }
    return baos.toByteArray();
}

and then in getStream() method return new InputStream every time:

@Override
public InputStream getStream() {
    return new ByteArrayInputStream(ent);
}

edit Solution #2: Like @Hink suggested in the comment you can also call reset() on your Stream object.

Community
  • 1
  • 1
kukis
  • 4,489
  • 6
  • 27
  • 50
  • Is is normal memory stream, so You stimulated me to get such idea to add simple command **ent.reset();**. It works. I will accept it. – Hink Jun 26 '15 at 15:23