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, но это должно привести вас в правильном направлении.