AbstractResource.ResourceResponse блокирует пользовательский интерфейс при записи в OutputStream

Я хочу скачать CSV-файл с помощью Wicket, реализовав AbstractResource. Это выглядит примерно так:

public class ExportCsvFileResource extends AbstractResource 
{
   @Override
   protected AbstractResource.ResourceResponse newResourceResponse(IResource.Attributes attributes) 
   {
        AbstractResource.ResourceResponse resourceResponse = new AbstractResource.ResourceResponse();
        resourceResponse.setContentType("text/csv");
        resourceResponse.setFileName("exported-contacts-file.csv");
        resourceResponse.setTextEncoding("utf-8");
        resourceResponse.setWriteCallback(new AbstractResource.WriteCallback() 
        {
            @Override
            public void writeData(IResource.Attributes attributes) throws IOException 
            {
                OutputStream stream = attributes.getResponse().getOutputStream();
                generateContentInBatches(stream);
            }
        });
        return resourceResponse;
    }
    private void generateContentInBatches(OutputStream stream) 
    {
        int numberOfChunks=//...
        for (int i=0; i<numberOfChunks; i++) 
        {
            byte[] contentChunk = retrieveContentFromBackend(i);
            IOUtils.write(contentChunk, stream);
        }  
    }
}

Проблема заключается в том, что в то время как контент генерируется с помощью функции retrieveContentFromBackend (что занимает довольно много времени), пользовательский интерфейс не отвечает. Я нажимаю кнопки и т. Д., Но ничего не происходит, только после завершения создания файла я могу снова использовать интерфейс.

Как избежать блокировки пользовательского интерфейса во время постепенной генерации файла?

2 ответа

Решение

Взгляните на RequestMapperApplication и MapperDemoResourceReference из wicket-examples.

Вы можете смонтировать ссылки на ресурсы:

mountResource("/print/${sheet}/${format}", new MapperDemoResourceReference());

Чтобы загрузить такой ресурс без блокировки страницы, вам необходимо отобразить ссылку, которая непосредственно активирует ресурс:

add(new WebMarkupContainer("link")
{
    @Override
    protected void onComponentTag(ComponentTag tag)
    {
        super.onComponentTag(tag);

        PageParameters parameters = new PageParameters();
        parameters.add("sheet", "sheet1");
        parameters.add("format", "A4");
        tag.put("href", urlFor(new MapperDemoResourceReference(), parameters));
    }
});

Вот пример ленивой загрузки:

http://www.wicket-library.com/wicket-examples/ajax/lazy-loading?1

Я не знаю, как это работает с вашим объектом AbstractResource, но это должно привести вас в правильном направлении.

Другие вопросы по тегам