Wicket 1.5 でファイルダウンロード
Wicket 1.5 になってAbstractResourceStreamWriterがかなり変わってる。
AbstractResourceStreamWriterはwicket-coreにあるんだけど、IResourceStreamやAbstractResourceStreamはwicket-utilにある。
rc2だからまだ作ってる最中なんだろうか。
取り敢えずAbstractResourceStreamWriterを使ってみたら、実装する必要があるメソッドが多くて、writeの引数がOutputStreamではなくResponseになってる。
どういう意図で変更されたのか分かってないが、取り敢えず以前と同じように使うためのクラスを書いた。
import org.apache.wicket.request.Response; import org.apache.wicket.util.resource.AbstractResourceStream; import org.apache.wicket.util.resource.IResourceStreamWriter; import org.apache.wicket.util.resource.ResourceStreamNotFoundException; import org.apache.wicket.util.time.Time; @SuppressWarnings("serial") public abstract class SimpleResourceStreamWriter extends AbstractResourceStream implements IResourceStreamWriter{ @Override public InputStream getInputStream() throws ResourceStreamNotFoundException { throw new IllegalStateException("getInputStream is not used with IResourceStreamWriter"); } @Override public Time lastModifiedTime() { return Time.now(); } @Override public void close() throws IOException { } /** * @see org.apache.wicket.request.resource.AbstractResource#writeStream */ @Override public void write(final Response response) { OutputStream out = new OutputStream(){ @Override public void write(int b) throws IOException { response.write(new byte[] { (byte)b }); } @Override public void write(byte[] b) throws IOException { response.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { if (off == 0 && len == b.length) { write(b); } else { byte copy[] = new byte[len]; System.arraycopy(b, off, copy, 0, len); write(copy); } } }; write(out); } protected abstract void write(OutputStream out); }
// 使い方 add(new Link<Void>("test"){ @Override public void onClick() { final HSSFWorkbook book = new HSSFWorkbook(); book.createSheet("test"); IResourceStream resourceStream = new SimpleResourceStreamWriter(){ @Override protected void write(OutputStream out) { try { book.write(out); } catch (IOException e) { throw new WicketRuntimeException(e); } } }; getRequestCycle().scheduleRequestHandlerAfterCurrent( new ResourceStreamRequestHandler(resourceStream) .setFileName("book.xls").setContentDisposition(ContentDisposition.ATTACHMENT)); } });
元々存在するファイルはDownloadLinkで簡単にリンクを作れるので、一時ファイルを作ってからDownloadLinkを使ってもいいかも。