S-JIS[2015-05-06] 変更履歴

FreeMarker MethodModel

FreeMarkerで独自のメソッドを定義する方法について。


概要

FreeMarkerでは、プログラマーが独自にメソッド(関数)を作成して、テンプレートファイルから呼び出すことが出来る。

TemplateMethodModelExインターフェースを実装したTempleteModelクラスを作成し、ルートのデータモデルに入れておくだけでよい。


TemplateMethodModelExクラス:

package com.example.freemarker.method;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
public class MyMethodModel implements TemplateMethodModelEx {

	@Override
	public Object exec(@SuppressWarnings("rawtypes") List arguments) throws TemplateModelException {
		if (arguments.size() < 1) {
			throw new TemplateModelException("Wrong arguments");
		}

		TemplateScalarModel model = (TemplateScalarModel) arguments.get(0);
		return "実験" + model.getAsString();
	}
}

実装するメソッドはexec()のみ。
引数はTempleteModelのリストだが、ジェネリクスが定義されていない。

戻り値はTemplateModelである必要は無い。(自動的にTemplateModelにラップされる)


テンプレート適用メインクラス:

		// データモデルを定義
		Map<String, Object> dataModel = new HashMap<>();
		dataModel.put("myMethod", new MyMethodModel()); //メソッド名をキーにして、処理オブジェクトを登録する

		template.process(dataModel, writer);

テンプレートファイル:

カスタムメソッドの実験: ${myMethod("zzz")}

DeepUnwrap

TemplateMethodModelEx#exec()の引数からJavaBeansを受け取りたいような場合は、DeepUnwrapを使うのが便利。

import freemarker.template.TemplateModel;
import freemarker.template.utility.DeepUnwrap;
	@Override
	public Object exec(@SuppressWarnings("rawtypes") List arguments) throws TemplateModelException {
		TemplateModel model = (TemplateModel) arguments.get(0);
		Object object = DeepUnwrap.unwrap(model);
		if (object instanceof MyBean) {
			〜
		}
		〜
	}

FreeMarker目次へ戻る / Javaへ戻る / 技術メモへ戻る
メールの送信先:ひしだま