前の記事でIncludeクラスのエンコード設定がおかしいため、JspTemplateEngineで文字化けが発生する問題を取り上げましたが、今回はそれを回避するコードを書いてみました。
IncludeクラスのInstanceを1回作成し、setDefaultEncodingを実行すればstaticなフィールドにデフォルトエンコードが設定されるのでContextListenerの中でそういったコードを書きます。
ContextListenerの中でDispatcherへListenerを追加します。そしてそのListenerの中で初期化処理を行います。なぜこういう風にするのかと言うと、Struts2のコントローラーはFilterで実装されています。ContextListenerで直接初期化処理を書いてしまうと、Filterの初期化よりも前に実行されてしまい、Struts2の初期化処理が行われていない状態で実行されてしまう事になるからです。
public class DefaultContextListener implements ServletContextListener { private DispatcherListener dispatchListener = new DispatcherListener() { private ValueStackFactory valueStackFactory; private String defaultEncoding; @SuppressWarnings("unused") @Inject public void setValueStackFactory(ValueStackFactory valueStackFactory) { this.valueStackFactory = valueStackFactory; } @Inject(StrutsConstants.STRUTS_I18N_ENCODING) @SuppressWarnings("unused") public void setDefaultEncoding(String val) { defaultEncoding = val; } @Override public void dispatcherInitialized(Dispatcher du) { du.getContainer().inject(this); ValueStack stack = valueStackFactory.createValueStack(); new Include(stack, null, null).setDefaultEncoding(defaultEncoding); } @Override public void dispatcherDestroyed(Dispatcher du) { } }; @Override public void contextInitialized(ServletContextEvent sce) { Dispatcher.addDispatcherListener(dispatchListener); } @Override public void contextDestroyed(ServletContextEvent sce) { Dispatcher.removeDispatcherListener(dispatchListener); } }