Wicket の AjaxButton でファイルダウンロードを実装しようと、ファイルダウンロードの方法自体に、いろんな方法があるだろうけど、、
IRequestHandler handler = new ResourceStreamRequestHandler(resource,downloadName);
getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
など、scheduleRequestHandlerAfterCurrent を使うよくある方法、
でももう一度探したら、Wicket6 のドキュメントで以下のページを発見、
https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow
でも、AjaxButton の onSubmit で、RequestCycle の replaceAllRequestHandlers を実行する PageClass に、setResponsePage すれば済むことである。
それでも見つけた上のURLページに書いてある AjaxBehavior の方法は興味深いので、
余計なものを削除して書き直してみる。
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.request.resource.ContentDisposition;
import org.apache.wicket.util.resource.IResourceStream;
/**
* AJAXDownload.
*/
public abstract class AJAXDownload extends AbstractAjaxBehavior{
protected abstract IResourceStream getResourceStream();
/**
* ダウンロード実行.
* @param target AjaxRequestTarget
*/
public void callBackDownload(AjaxRequestTarget target){
target.appendJavaScript("setTimeout(\"window.location.href='" + getCallbackUrl().toString() + "'\", 100);");
}
@Override
public void onRequest(){
try{
ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(getResourceStream(), URLEncoder.encode(getFileName(), "UTF-8"));
handler.setContentDisposition(ContentDisposition.ATTACHMENT);
getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
}catch(UnsupportedEncodingException e){
throw new RuntimeException(e.getMessage(), e);
}
}
protected String getFileName(){
return null;
}
}
これを使う WebPage のサンプル、、、
public class AjaxButtonTypePage extends WebPage{
String info;
String downloadname;
public AjaxButtonTypePage(){
final TextField<String> infoField = new TextField<String>("info", new Model<String>());
final TextField<String> downloadnameField = new TextField<String>("downloadname", new Model<String>());
final AJAXDownload download = new AJAXDownload(){
@Override
protected IResourceStream getResourceStream(){
return new AbstractResourceStreamWriter(){
@Override
public void write(OutputStream out){
try{
// TODO OutputStreamに、ダウンロードコンテンツを出力する。
// 可変なダウンロードコンテンツ出力をする為に、
// Text入力フィールドの値を、AjaxButton で
// getInput() → ページのインスタンス経由(※)で取得して
// ダウンロードコンテンツ出力のパターンが変わる。
// このサンプルは、ダウンロードファイル名を兼ねる
}catch(Exception e){
throw new RuntimeException(e);
}
}
@Override
public String getContentType() {
return "application/pdf";
}
};
}
@Override
protected String getFileName() {
return downloadname +".pdf";
}
};
Form<Void> form = new Form<Void>("form");
form.add(new AjaxButton("download"){
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> f){
info = infoField.getInput();
downloadname = downloadnameField.getInput();
// コールバックでダウンロード実行
download.callBackDownload(target);
}
}.add(download));
form.add(infoField);
form.add(downloadnameField);
add(form);
}
}
===============
Form 入力に従い、AjaxButton の機能を使いつつ、他のUIの部品と共存させる画面も可能であろう。