Home > 開発 > Struts2 Archive

Struts2 Archive

Struts2のJspTemplateEngineで文字化けを起こさないようにする初期設定

前の記事で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);

	}

}

 

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をつけるみたいで気がつきませんでした。

(○口○*) はぁ・・

Struts2の拡張子無し

  • Posted by: タムタム
  • 2007年12月17日 11:45
  • Struts2

Struts2.0.11で拡張子無しのアクセスが上手くいきません・・・。

標準ではstruts.action.extensionが"action"に設定されており、これを""に設定するとjspに直アクセスできなくなります。JSPに直アクセスするなら転送用のActionを挟むと思いますが、念のため調査しました。
DefaultActionProxyをステップ実行させました。どうやらBugの様子。BugDBを見たら登録されており、既に修正済みとのこと。
https://bugzilla.spamassassin.org/struts/browse/WW-2163

Struts2.1.0のリリースに組み込まれるようなので、それまで待つ必要はありますが・・。
バイナリはこちらからダウンロードできます。
http://people.apache.org/builds/struts/2.1.0/

なお、設定は""で設定しても上手く動きません。以下のように設定する必要があります。

<constant name="struts.action.extension" value="," />

これもどうかとは思いますが(´・ω・)
ちなみにStruts2.1は未リリースです。いつ頃出るのでしょうか・・。
当然ながらStruts2はxworkがベースになっているためstruts2.1系はxworkも2.1系になります。

 

Struts2.1に差し替えた時にEclipseのWTPではまったこと。
サーバのCleanをしないと古いJARファイルも残っててかち合っちゃいました。。

Struts2.0.11 リリース

  • Posted by: タムタム
  • 2007年10月29日 22:52
  • Struts2

Struts2.0.11がリリースされてるううううぅ!
メーリングリストの流れから察してそろそろ来るとは思っていましたが、2.0.9のソース精査が終わった直後にリリースとは・・・。やってくれますね(涙)

2.0.11のリリースノートはこちらです。

struts2のお勉強

  • Posted by: タムタム
  • 2007年10月27日 21:43
  • Struts2

台風が接近中です。ワクワクテカテカ。

さてstruts2をお勉強というか、調査中です。
調べれば調べるほど便利だなーと思うのですが、これをプロジェクトで使うためにどうやって周知しようかなと悩みどころです。Struts1はまったくの別物ですし・・。ただ、古くさい実装は殆ど排除されていてとても使いたい。
Struts1を文句を垂れながら改造して使うよりも、最近の流行を取り込んでいるStruts2を勉強して使った方が良いと思うのですよ。もちろん、今までのノウハウは使えませんけどね・・。

さて、設定ファイルベースのValidationが動作しないと1時間ほど悩んでいたのですが、原因がわかりました。。
設定ファイルの名前間違ってた・・・orz
「アクションクラス名-validation.xml」、または「アクションクラス名-アクション名-validation.xml」と理解はしていたのですが、アクションクラス名が「SayHelloAction」、ファイル名を「SayHello-validation.xml」としていました。「SayHelloAction-validation.xml」が正しいのにね(ぐすん)

このValidationの設定は他にもアノテーションを使う方法とアクションクラス内でロジックを書く方法があります。
そのうちWikiに載せます。


勉強といえば、この前の休みは情報処理の国家試験だったようですねー。
誰か受けた人いないかな?
最近の試験はどんなもんなんでしょ。
私も今度受けてみようかな。

Continue reading

Home > 開発 > Struts2 Archive

Search
Feeds

Return to page top