Wicket8 が前提の話だが、ビヘビアをラムダで。。を考え出すと、次から次へと出てくる。。。
AJAX の振る舞いで動かすダウンロード、以前、
Wicket 6.x→7.x でファイルダウンロード時のファイル名の注意 - Oboe吹きプログラマの黙示録
この中で、public abstract class AJAXDownload を書いた。
でもこれは、以下のように、インスタンス生成の staticメソッド-ラムダを用意すれば、
もう少しスッキリする。
import java.io.IOException; import java.io.OutputStream; 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.AbstractResourceStreamWriter; import org.apache.wicket.util.resource.IResourceStream; import org.danekja.java.util.function.serializable.SerializableConsumer; import org.danekja.java.util.function.serializable.SerializableSupplier; /** * AJAX Download. */ public abstract class AJAXDownload extends AbstractAjaxBehavior{ protected abstract IResourceStream getResourceStream(); public void callBackDownload(AjaxRequestTarget target){ target.appendJavaScript("setTimeout(\"window.location.href='" + getCallbackUrl().toString() + "'\", 100);"); } @Override public void onRequest(){ try{ ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(getResourceStream(), getFileName()); handler.setContentDisposition(ContentDisposition.ATTACHMENT); getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler); }catch(Exception e){ throw new RuntimeException(e.getMessage(), e); } } protected String getFileName(){ return null; } public static AJAXDownload of(SerializableConsumer<OutputStream> write , SerializableSupplier<String> getConteType, SerializableSupplier<String> getName){ return new AJAXDownload(){ @Override protected IResourceStream getResourceStream(){ return new AbstractResourceStreamWriter(){ @Override public void write(OutputStream out) throws IOException{ write.accept(out); out.close(); } @Override public String getContentType(){ return getConteType.get(); } }; } @Override protected String getFileName(){ return getName.get(); } }; } }
とすれば、、
final AJAXDownload download = AJAXDownload.of(out->{ // out への出力 }, ()->"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ()->"foo.xlsx"); compoment.add(download); queue(AjaxLink.onClick("download", t->{ // 出力準備の後で、、 download.callBackDownload(t); }).add(download));
OutputStream の close の書き忘れを気にしなくてよい。