我们正在开发一个Vaadin应用程序,在oc4j 10.1.3上运行它。有一个窗口,可以将查询结果导出为csv文件。将csv文件创建为vaadin FileResource后,打开文件失败。 这是片段:
File file = exporter.exportToFile();
final FileResource resource = new FileResource(file, getApplication());
resource.setCacheTime(0);
resource.getStream().setParameter("Content-Disposition", "attachment;filename=\""+file.getName()+"\"");
event.getButton().getWindow().open(resource);
此时,资源的uri是:app://APP/1/xy.csv
我们有一个过滤器,用于重定向“/ VAADIN”的“/”路径。调用此过滤器时,文件的uri为/VAADIN/APP/1/xy.csv
而不是/APP/1/xy.csv
,因此我删除了不必要的/ VAADIN部分,并使用新的uri调用requestdispatcher.forward
。
但这是有趣的部分,应用程序仍然失败,它在日志中说:
Aug 13, 2012 1:55:58 PM com.vaadin.terminal.gwt.server.AbstractApplicationServlet serveStaticResourcesInVAADIN
INFO: Requested resource [VAADIN/APP/1/xy.csv] not found from filesystem or through class loader. Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder.
所以uri又错了。它出现在地址栏中,应用程序将重置为主页面。但是,由于此uri仍在地址栏中,当我尝试再次创建csv文件时,在应用程序中执行相同的其他查询时,导出部分会返回一个文件,即先前生成的文件。如果我再次尝试再次执行另一个查询(前一个URL仍然在浏览器的地址栏中),它似乎会生成新的csv文件,但会再次返回第一个文件。
是vaadin bug还是某些oc4j魔法? :)
答案 0 :(得分:0)
Vaadin框架适用于服务器端。那么为什么需要在服务器上创建不必要的临时CSV文件?尝试将所需数据直接导出到流中。
如果您需要导出少量数据,只需使用ByteArrayOutputStream和Vaadin StreamResource即可。将您的CSV值写入OutputStream并将此流提供给以下功能:
public void openResourceFromStream(final OutputStream out, String filename) {
StreamSource streamSource = new StreamSource() {
private static final long serialVersionUID = 1L;
@Override
public InputStream getStream() {
ByteArrayOutputStream byteStream = (ByteArrayOutputStream) out;
return new ByteArrayInputStream(byteStream.toByteArray());
}
};
Resource sr = new StreamResource(streamSource, filename, getApplication());
getWindow().open(sr, "_parent");
}
如您所见,此代码执行从OutputStream到InputStream的简单对话,并使用结果InputStream来创建Vaadin StreamResource对象。
'filename'参数设置将在客户端加载到浏览器中的文件的默认名称(注意,该用户始终可以使用“始终显示保存对话框”浏览器选项“在运行中”重命名文件)。
当然,这个变体有点难看,因为它将所有导出的数据保存在内存中。
如果您需要导出大量数据并且不想将所有数据保存在内存中,则可以使用PipedOutputStream或自定义循环缓冲区而不是ByteArrayOutputStream字节缓冲区。 算法将是相同的。见article about OutputStream to InputStream conversation 和Vaadin book chapter about resources了解更多信息。
P.S。在数据导出成功后,不要忘记完全关闭输入和输出流。