wicket:如何从数据库流式传输资源



我正试图为一个拥有数千个页面的大型网站动态生成网站地图。

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

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

我遵循了WicketSEO页面上的说明,并能够使用DataProvider实现动态站点地图。但它不可扩展——当它调用DataProvider的iterator()方法时,它会耗尽内存,count参数等于我返回的对象总数,而不是按块迭代它们。

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

来自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实现告诉长度是未知的,并且在从数据库获取记录时直接流式传输数据,这是可以的。

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

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

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

我最终使用了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);
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新