Wicket で原始的な Response を使う注意の1つ

Wicket に文句をつけたいところは、getRequestCycle で引っ張ってくるオブジェクトのインターフェースが
今まで、何度も実装が変わってきたことだ。。
8年前は、、、

HttpServletRequest request = getWebRequestCycle().getWebRequest().getHttpServletRequest();
HttpServletResponse response = getWebRequestCycle().getWebResponse().getHttpServletResponse();

が成立したが、、Wicket 8.x 以降では、これはNGである。
⇒ http://oboe2uran.hatenablog.com/entry/2010/09/15/211605 これは今やとなってはNG

org.apache.wicket.request.http.WebResponse

WebResponse webresponse = (WebResponse)getRequestCycle().getResponse();

原始的なことをするなら、この WebResponse で実行することが基本だ。
WebResponse には、getContainerResponse() というメソッドがあるが、これはあくまでもWebコンテナに依存した
クラスを返す。Tomcat の時は、org.apache.catalina.connector.ResponseFacade が返ってくれる。

getRequestCycle().getResponse() の使用例
判りやすく、昨日の投稿に合わせて、、、画像を返す WebPage 継承クラスである。

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.request.http.WebResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * SampleResponseImage
 * 画像は、、リソースの下、/img/canion.jpg
 */
public class SampleResponseImage extends WebPage{
   Logger logger = LoggerFactory.getLogger(this.getClass());

   public SampleResponseImage(){
      String classesPath = ((WebApplication)getApplication()).getServletContext().getRealPath("WEB-INF/classes");
      File fileCanion = new File(classesPath + "/img/canion.jpg");

      WebResponse webresponse = (WebResponse)getRequestCycle().getResponse();
      webresponse.setContentType("image/jpeg");
      try(InputStream in = new FileInputStream(fileCanion);OutputStream out = webresponse.getOutputStream()){
         in.transferTo(out);
      }catch(Exception ex){
         logger.error(ex.getMessage(), ex);
      }
   }
}

WebApplicarion の init() で、

mountPage("/SampleResponseImage", SampleResponseImage.class);

HTML

<img src="/samples/SampleResponseImage" width="20%" height="20%">

わざわざ、Wicket から原始的なオブジェクトを取得して処理するのは、
Wicket が折角提供する各種コンポーネントを利用しないことになってセンスがないかもしれない。
でも、原始的な処理の面倒なところから、簡単な記述で済むようなコンポーネントの提供まで、
柔軟にいろいろ書くことが許されているのが魅力なんだと思う。
しかし、この getRequestCycle() 回りは、過去から今まで何度も変更があって、
困ったものだ。
ServletAPI 2.3→ 2.5 → 3.0 → 3.1 → 4.0 → 4.1 と歴史上、仕方なかったのだろうか?。。。