静的コンテンツを表示するHTMLに動的な値を表示したい
プロジェクトの実行環境はJerseyのため、画面はJSPにより動的に生成されるHTMLで表示する想定であったが、静的コンテンツのみを扱う画面のためHTMLで表示を行いたいとの要望があった。
このため、Jersey/JSPによる画面の表示はやめ、servletによりサーバ上のHTML(モジュールのクラスパス外)を取得画面に表示するようにした、という経緯がある。
しかし、このHTMLに動的な値を出したいという要望があり、対応することとなった。
(初めから動的な値を表示するのであればJSPにしていたのに。。。)
対象のモジュールはすでに本番リリースをしているモジュールであるため、影響度をできる限り抑えたいとのことでHTML→JSPへの変換は却下された。。。
そこで、別のプロジェクトでもHTMLに動的な値を埋め込むために使用した実績のあるVelocityを使うことに。
そんなわけで、その時に手こずったところを中心に思いつくままにメモメモ。。
クラスパス外の任意のフォルダのHTMLファイルをテンプレートファイルにする
設定ファイルによってデフォルトのリソースローダを指定したところ、ファイルが見つからない旨のエラーが発生。
⇒設定ファイルのテンプレートファイルの配置先を指定するプロパティがデフォルト値「.(クラスパスルート)」となっており、任意のディレクトリがクラスパスルート直下に存在しなかったためエラーとなっていた。
⇒テンプレートファイルの指定はフルパスで行っているため、配置先のプロパティを使わないという意味をこめ設定ファイルに「配置先のプロパティ名= 」(未指定)としたところ、、これもエラー。。
設定ファイルを用いず、javaコード内でプロパティを設定
javaのコード内でVelocityのインスタンス生成時に動的にプロパティを設定することができる。(Propertiesクラスを用いる)
setProperty("配置先のプロパティ名", "")
(空文字を設定)としたところ、配置先のプロパティを見ずにテンプレートファイルの指定のみを見るように動作、テンプレートファイルを読み込むことに成功した。
正常動作したコードは以下。
ServletOutputStream out = response.getOutputStream(); //HttpServletResponse
String pathName = "/hogehoge";
//Velocityの初期化
Properties p = new Properties();
p.setProperty("input.encoding", "UTF-8");
p.setProperty("output.encoding", "UTF-8");
p.setProperty("resource.loader", "file");
p.setProperty("file.resource.loader.path", ""); // ※このプロパティの値を空にしたいが、設定ファイルだと上手く空にならない。。。このためPropertiesで設定する
p.setProperty("file.resource.loader.class", FileResourceLoader.class.getTypeName());
p.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
p.setProperty("runtime.log.logsystem.log4j.category", "velocity");
p.setProperty("runtime.log.logsystem.log4j.logger", "velocity");
Velocity.init(p);
//Velocityコンテキストに値を設定
VelocityContext context = new VelocityContext();
context.put("userName", "hogehoge";
StringWriter sw = new StringWriter();
//テンプレートの作成
Template template = Velocity.getTemplate(pathName);
//テンプレートとマージ
template.merge(context,sw);
byte[] bytes = sw.toString().getBytes("UTF-8");
out.write(bytes);
out.flush();