【问题标题】:wicket: how to stream a resource from a databasewicket:如何从数据库中流式传输资源
【发布时间】:2011-06-09 02:16:48
【问题描述】:

我正在尝试为具有数千个页面的大型网站动态生成站点地图。

是的,我考虑过离线生成站点地图文件并简单地静态提供它,我最终可能会这样做。但我认为这是一个普遍有用的问题:

如何从 Wicket 中的数据库流式传输大量数据?

我按照Wicket SEO page 的说明进行操作,并能够使用 DataProvider 获得一个动态站点地图实现。但它不能扩展 - 当它调用我的 DataProvider 的 iterator() 方法时,它会耗尽内存,而 count arg 等于我返回的对象总数,而不是在块中迭代它们。

我认为解决方案在于WebResource/ResourceStreamingRequestTarget。但是这些类需要一个IResourceStream,最终归结为提供一个InputStream 实现,它以字节而不是数据库记录来处理。在这种情况下,我不知道如何实现 length() 方法,因为这需要提前访问每条记录以计算总长度。

【问题讨论】:

    标签: stream streaming wicket


    【解决方案1】:

    来自 IResourceStream.length() 方法的文档:

        /**
     * Gets the size of this resource in bytes
     * 
     * TODO 1.5: rename to lengthInBytes() or let it return some sort of size object
     * 
     * @return The size of this resource in the number of bytes, or -1 if unknown
     */
    long length();
    

    所以我认为,如果您的 IResourceStream 实现告诉您长度未知并且您在从数据库中获取记录时直接流式传输数据。

    【讨论】:

      【解决方案2】:

      您可以返回 -1,表示未知长度,或者您可以将结果写入内存缓冲区或磁盘,然后再将其呈现给客户端。

      您也可以将此文件用作缓存,这样您就无需在每次请求此资源时都重新生成它(但请记住,您必须处理并发请求)。也可以考虑使用专用的缓存解决方案(例如 memcache、ehcache 等)。

      它可能比发布静态文件更干净,尽管如果性能很关键,静态文件可能会更好。

      【讨论】:

        【解决方案3】:

        我最终使用了AbsractResourceStreamWriter 子类:

        public class SitemapStreamWriter extends AbstractResourceStreamWriter
        {
            @Override
            public void write(OutputStream output)
            {
                String HEAD = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                              "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n" +
                               "        xmlns:wicket=\"http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd\">\n";
                try
                {
                    output.write(HEAD.getBytes());
        
                    // write out a <loc> entry for each of my pages here
        
                    output.write("</urlset>\n".getBytes());
                }
                catch (IOException e)
                {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-30
          • 2019-10-29
          • 2011-05-22
          • 1970-01-01
          • 2015-12-02
          • 1970-01-01
          • 2018-03-30
          • 2022-01-04
          相关资源
          最近更新 更多