У меня есть простая форма Wicket, которая позволяет пользователям выбирать некоторые данные и затем загружать ZIP-файл (созданный на лету), содержащий то, что они просили. В настоящее время метод onSubmit()
кнопки формы выглядит примерно так:
public void onSubmit() {
IResourceStream stream = /* assemble the data they asked for ... */ ;
ResourceStreamRequestTarget target = new ResourceStreamRequestTarget(stream);
target.setFileName("download.zip");
RequestCycle.get().setRequestTarget(target);
}
Это работает, но, конечно, запрос на этом останавливается, и невозможно отобразить какие-либо другие отзывы для пользователя.
Мне хотелось бы получить что-то вроде «Запрошенная загрузка [ИМЯ] должна начаться автоматически. Если нет, нажмите на эту ссылку». В идеале, по-прежнему отображается та же страница, поэтому пользователь может сразу выбрать несколько различных данных и загрузить их.
Я полагаю, что это можно сделать с помощью классов Ajax Wicket, но мне удалось избежать их использования до сих пор, и для меня не сразу понятно, как это сделать. Какой у меня самый быстрый выход, здесь?
Обновлено за ответ от Зератула, ниже: у меня получилось что-то вроде этого:
class MyDownloader extends AbstractAjaxBehavior {
private final MyForm form;
MyDownloader(MyForm form) {
this.form = form;
}
void startDownload(AjaxRequestTarget target) {
target.addComponent(myForm);
target.appendJavascript("window.location.href='" + getCallbackUrl() + "'");
}
@Override
public void onRequest() {
try {
ResourceStreamRequestTarget streamTarget = form.getStreamTarget();
form.info(/* some status message */);
getComponent().getRequestCycle().setRequestTarget(streamTarget);
catch (SomeException e) {
form.error(e.getMessage());
}
}
}
class MyForm extends Form {
private final MyDownloader myDownloader;
private final Object myModel;
MyForm(Object aModel) {
super("myForm");
myModel = aModel;
myDownloader = new MyDownloader(this);
add(myDownloader);
add(/* form components */);
add(new AjaxButton("download", new Model<String>("Download"), this) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
myDownloader.startDownload(target);
}
});
add(new FeedbackPanel("feedback"));
}
ResourceStreamRequestTarget getStreamTarget() throws SomeException {
return /* target based on form input */;
}
}
Это кажется немного шатким, но, похоже, работает.