使用StreamResource再次点击Vaadin链接并不起作用

时间:2015-06-25 07:49:40

标签: hyperlink inputstream vaadin

我有来自其他服务器的InputStream(来自JasperReports的PDF文件),用户可以下载它。

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

如果打印服务器返回页面,&#34;下载报告&#34;将出现,用户可以通过点击下载PDF文件。但第二次点击同一链接失败。它可能会返回空内容。怎么了?也许我必须回滚输入流。怎么样?

1 个答案:

答案 0 :(得分:2)

那是因为你的getStream()方法返回相同的流,并且只能从它们读取一次流。在流中使用数据后,数据将不再可用。

您可能需要先使用此方法将InputStream转换为字节(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();
}

然后在getStream()方法中每次都返回新的InputStream:

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

编辑解决方案#2:与评论中建议的@Hink一样,您也可以在Stream对象上调用reset()。