JspTemplateEngineのBug(Struts2.1.6)

結論から言うと、JSPを使ったカスタムタグを作るときにEncodingの指定を読み込めず(システムのデフォルトの文字コード)を使うようになって文字化けが発生するというバグが存在しました。

Struts2.1.6でカスタムタグを作るときにデフォルトではFreeMarkerを使うようになっていますが、VelocityやJSPもテンプレートとして使うことができます。struts.xmlでデフォルトのエンジンを変更するか、自作のカスタムタグでテンプレート名を明示的に拡張子付きで指定してあげます。(例:hogehoge.jsp)

さて、JspTemplateEngineはRequestDispatcherのIncludeを使って実装されています。
このIncludeをする部分はカスタムタグのInclude(<s:include>)のstaticなメソッドであるincludeを呼んでいます。

ソースをひもといていくと、、、

private static String defaultEncoding;
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
public void setDefaultEncoding(String encoding) {
    defaultEncoding = encoding;
}

Σ(´Д`lll)エエ!!

しかも、defaultEncodingとは別にencodingってフィールドも持っているのですがこれもstaticなわけです。
これはひどい実装だ・・。 分けている意味が分からない。。。defaultがstaticでencodingがnon-staticだったら意味はわかるのですが・・・。

しかも、struts-default.xmlのBeanの定義には↓こう書いてある。

<bean class="org.apache.struts2.components.Include" static="true" />

staticなinjectionをしますよと書いてあるのにかかわらず、Setterはstaticではないのです!!
誰がこんなコードを何のために修正したんだろうと思ってレポジトリ追ってみた。

http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Include.java?r1=554226&r2=577728

ここで変更されたみたい。

 

ちなみに、先に<s:include>タグを実行すると、インスタンス化されて普通に@Injectが走ってstaticフィールドに設定されて以降はその文字コードを使うようにします。WTPだとデフォルトでfile.encoding=UTF-8をつけるみたいで気がつきませんでした。

(○口○*) はぁ・・

新しいサイトもよろしくお願いします!