Wicket でファイルダウンロード

2014 年 8月 22日に、このページのメモよりも、改善すべく書き直した。。

===========================
Wicket でファイルダウンロードの方法は、、

動的にストリーム出力ダウンロードは、以下のように、IRequestHandler でダウンロードさせることが
一般的?よく見かける方法

IRequestHandler handler = new ResourceStreamRequestHandler(resource,downloadName);
getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);

しかしこれは、AbstractResourceStreamWriter#getContentType()で Content-type を指定する方法があるが、
Content-Length をセットするためのメソッドはない。

   @Override
   public String getContentType(){
      return "image/jpeg; Content-Length: "+jpgfile.length()+";";
   }
というのはダメみたい。



次は、静的なファイルダウンロード
Pageクラスと同じ場所にファイルを置いて、常に同じファイルを返す方法、、

URLパラメータ、taget=ファイル名、type=mimeType でダウンロードするもの。。
ファイルは、このクラスと同じ階層に存在するものとする。

import java.io.File;
import java.net.URISyntaxException;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.request.IRequestParameters;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.request.http.WebResponse;
import org.apache.wicket.util.resource.FileResourceStream;
/**
 * DownLoader
 */

public class DownLoader extends WebPage{

   public DownLoader() throws URISyntaxException{
      IRequestParameters params = getRequest().getQueryParameters();

      String type = params.getParameterValue("type").toString();
      String fileName = params.getParameterValue("target").toString();

      final File file = new File(getClass().getResource(fileName).toURI());

      WebResponse webresponse = (WebResponse)getResponse();
      webresponse.setContentType(type);
      webresponse.setContentLength(file.length());
      webresponse.setInlineHeader(fileName);
      webresponse.setAttachmentHeader(fileName);

      getRequestCycle().setResponse(webresponse);
   }
}
-----------------------------------

もしくは、WebResponse を使わずに、、、

import java.io.File;
import java.net.URISyntaxException;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.request.IRequestParameters;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.util.resource.FileResourceStream;
/**
 * DownLoader
 */

public class DownLoader extends WebPage{

   public DownLoader() throws URISyntaxException{
      IRequestParameters params = getRequest().getQueryParameters();

      String fileName = params.getParameterValue("target").toString();

      final File file = new File(getClass().getResource(fileName).toURI());
      getRequestCycle().scheduleRequestHandlerAfterCurrent(
         new ResourceStreamRequestHandler(new FileResourceStream(file),fileName)
      );
   }
}
==============================

DownLoader.html は、以下1行のみ。

<!DOCTYPE html>

WebApplication で、mount を用意

   protected void mymount(String mountPath, Class<? extends WebPage> pageClass){
      getRootRequestMapperAsCompound().add(new MountedMapper(mountPath,pageClass));
   }

WebApplication init() の中で
   mymount("/DownLoader",DownLoader.class);

リンクに割り当て、Lighthouse.jpg ダウンロードさせる。

WebMarkupContainer download = new WebMarkupContainer("download");
download.add(new AttributeModifier("href","/uran/DownLoader?target=Lighthouse.jpg&type=image/jpg"));
add(download);

リンク <a>タグに、rel="external" を付けるのを忘れずに!!