Develop with pleasure!

福岡でCloudとかBlockchainとか。

FreeMarkerのテンプレートファイルのロード処理を変更する。

Struts2+FreeMarkerの連携では、FreeMarkerのテンプレートファイルはweb.xml

<context-param>
  <param-name>templatePath</param-name>
  <param-value>C:/hoge/template</param-value>
</context-param>

な感じで指定する。
Struts2では、この設定を
org.apache.struts2.views.freemarker.FreemarkerManager
が読み込み、テンプレートファイルをロードする。

そのため、テンプレートファイルの設定をweb.xml以外にしたり設定変更を行いたい場合は、FreemarkerManagerを拡張すれば良い。設定を別ファイルや、JNDI等から読み込む場合は、FreemarkerManagerのgetTemplateLoaderメソッドをオーバーライドする。

import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.apache.struts2.views.freemarker.StrutsClassTemplateLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import freemarker.cache.TemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.WebappTemplateLoader;

import javax.servlet.ServletContext;
import java.io.File;
import java.io.IOException;

public class CustomFreemarkerManager extends FreemarkerManager {

  private static final Log LOG = LogFactory.getLog(CustomFreemarkerManager.class);

  @Override
  protected TemplateLoader getTemplateLoader(ServletContext servletContext) {
    FileTemplateLoader templatePathLoader = null;

    String templatePath = // このパスを設定する。

    if (templatePath == null) {
      LOG.error("templatePath is not define.");
      throw new IllegalArgumentException("templatePath is not define.");
    }

    try {
      templatePathLoader = new FileTemplateLoader(new File(templatePath));
    } catch (IOException e) {
      LOG.error("Invalid template path specified: " + e.getMessage(), e);
		}

     return templatePathLoader != null ?
       new MultiTemplateLoader(new TemplateLoader[]{
         templatePathLoader,
         new WebappTemplateLoader(servletContext),
           new StrutsClassTemplateLoader()
         })
         : new MultiTemplateLoader(new TemplateLoader[]{
         new WebappTemplateLoader(servletContext),
         new StrutsClassTemplateLoader()
      });
  }
}

で、後はStruts2が読み込むFreeMarkerManagerをstruts.xmlに定義する。

  <constant name="struts.freemarker.manager.classname" value="CustomFreemarkerManager"/>