【问题标题】:Vaadin Requested resource not foundVaadin 未找到请求的资源
【发布时间】:2012-08-15 15:07:44
【问题描述】:

我们正在开发一个 Vaadin 应用程序,在 oc4j 10.1.3 上运行它。有一个窗口,可以将查询结果导出为 csv 文件。将 csv 文件创建为 vaadin FileResource 后,打开文件失败。 这是sn-p:

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 错误还是一些 oc4j 魔法? :)

【问题讨论】:

    标签: java vaadin oc4j


    【解决方案1】:

    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 conversationVaadin book chapter about resources 了解更多信息。

    附:数据导出成功后不要忘记完全关闭输入输出流。

    【讨论】:

    • 感谢您的建议,但还是一样。正如书中在那一章中所说,We named the resource as myimage.png. The application adds a resource key to the file name of the resource to make it unique. The full URI will be like http://localhost:8080/testbench/APP/1/myimage.png. 这里也是一样,为流创建一个唯一的 URI,因为它是一个文件,同样的错误 uri 和我的转发仍然无用。是的,我们必须为大量的客户数据做准备,所以输出流->字节数组->输入流“转换”由于内存限制是不可接受的。
    • 我在 Chrome 中遇到了同样的问题,但在 Firefox 中没有。你解决了这个问题了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 2014-04-13
    • 1970-01-01
    相关资源
    最近更新 更多