javax.servlet.Filter

Webページ用の素材をSVGで作ってみている。

  • SVGを書く
  • Squiggleで確認する
  • batik-rasterizerで変換
  • 所定のディレクトリに置く
  • ブラウザで表示を確認する

この一連の作業が面倒で自動化しようと思い、勉強も兼ねてFilterからTranscoderを呼んでみた。
以下コード。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
    final ByteArrayOutputStream sourceOutputStream = new ByteArrayOutputStream();
    chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
        public PrintWriter getWriter() {
            return new PrintWriter(getOutputStream());
        }
        public ServletOutputStream getOutputStream() {
            return new ServletOutputStream() {
                public void write(int b) throws IOException {
                    sourceOutputStream.write(b);
                }
            };
        }
        public void setContentLength(int length) {}
        public void setContentType(String type) {}
    });
    byte[] sourceData = sourceOutputStream.toByteArray();
    ByteArrayOutputStream resultOutputStream = new ByteArrayOutputStream();
    try {
        Transcoder transcoder = new JPEGTranscoder();
        TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(sourceData));
        TranscoderOutput output = new TranscoderOutput(resultOutputStream);
        transcoder.transcode(input, output);
    } catch (TranscoderException ex) {
        ex.printStackTrace();
    }
    byte[] resultData = resultOutputStream.toByteArray();
    response.setContentType("image/jpeg");
    response.setContentLength(resultData.length);
    OutputStream out = response.getOutputStream();
    out.write(resultData);
    out.close();
}

Filter

データを変換するだけなのにAPIを追っかけるのに苦労した。既存のリクエストとレスポンスの実装を考えると、まぁこんなものだろうかと納得するのだけど、データ変換には向かない仕組みのように思う。
これだったらURLが多少雑になってもただのServletに任せるか、もしくはビルド側のAntスクリプトで変換したほうが良かったかも。

Transcoder

Batikのライブラリが細切れで何が必要で何が不要かさっぱりわからず、丸ごとWARに突っ込んだ。


いちいちその場で変換せずに初回のリクエストでファイルを作成するほうが良さそうだ。