Apache Tomcat 5.0.28+Strutsを使用しているとちょっと困った症状に出会いました。
StrutsのActionサーブレットでHttpServletRequest#getSession(false)のメソッドを用いても、新しいセッションを取得してしまうようです。ちょっとググってみると、Strutsでではないのですが、同様の問題で悩んでいる人がSeasarのMLでもいる模様です。
例えば、
HttpSession session = reqest.getSession(false);
if(session == null) {
// セッションタイムアウトのときの処理
}
を期待して、コーディングするとセッション切れのときは新しいセッションが作られてしまいセッションタイムアウトのときの処理が実行されません。
これを回避するには、あらかじめsessionに何かのオブジェクトを格納しておく方法をとると良さそうです。
例えば、ログインのActionServletにおいて
HttpSession session = req.getSession(true);
session.setAttribute("hoge","何かの文字列");
としておき、ログイン以外のServletにおいては、
HttpSession session = req.getSession(false);
if( (session == null) || (session.getAttribute("hoge") == null) ) {
// セッションタイムアウトのときの処理
}
とすると、新しいセッションが作成されたときに、HttpSession#getAttribute("hoge")がnullにならないのはログイン用のサーブレットを実行し、セッションタイムアウトしていない場合に限定されるので、うまく動作してくれます。
でも、状況的にApache Tomcat 5.0.28のバグの可能性が高そうだなぁ...
Strutsとセッションの話題をしたので、ついでにもう一つ良さそうな話題を紹介します。
@IT - 第4回 安全なセッション管理を実現するために
ここで公開されている内容は、Strutsのログインシステムを作る上で結構役に立ちそうです。
あるユーザでログイン後、セッションが切れる前にブラウザのログインページに戻って別のユーザでログインすると、前のユーザのログイン情報が残って危険な場合も考えられます。そのような問題も防げそうですね。
向こうの記事で十分説明されているので、敢えてこちらは講評だけにしておきます。
StrutsのActionFormを使っていると、validator()メソッドが結構便利です。
しかし、普通のActionServletでActionErrorを呼び出してエラーを表示させたい場合もあるじゃないですか。
そのための方法が、忘れっぽいエンジニアのJakarta Strutsリファレンス -
アクションクラスで生成したエラーのエラーメッセージを表示する<html:errors>に書かれていました。
ポイントは、
ActionMessages errors = new ActionMessages();
errors.add("userId", new ActionMessage("errors.required","ユーザーID"));
errors.add("userName", new ActionMessage("errors.invalid","名称"));
のようにActionMessageを用いてエラーを作成し、
saveErrors(request, errors);
return mapping.findForward("error");
のように、saveErrors(HttpServletRequest, ActionMessage)のメソッドを呼び出してから、findForward()メソッドを実行してやれば良いと。
簡単ですね。
そんなわけで備忘録としておいておきます∠( ̄∧ ̄)
Strutsのタグライブラリを用いたページを作っている最中に起きたトラブルへの備忘録です。
Strutsタグがない全てのページの基となるテンプレートページに、Strutsのタグライブラリを付け足しつつ編集していきました。
一通り完成したので、実際に動作させたところ、ページが表示されません。
「org.apache.struts.taglib.html.BEAN という名前のbeanが見つかりません」とエラーがでたものの、どこが原因になっているか分からない...orz
ググってみたところ、Java Look: formの要素のページが見つかりました。
ただし、なぜかindex.rdfの形で( ̄□ ̄;)!!
※上記のリンクはちゃんと普通のページにリンクしているのでご安心をw
ここを見て激しく高速に解決できました。
本来なら<html:form>タグの中に記述しなくてはいけない、<html:radio>、<html:checkbox>、<html:text>などのタグが<html:form>タグの外側に記述されているか、そのページに<html:form>タグがそもそも記述されていないかのどちらかです。
ちなみに、俺の場合、全てのページの基となるテンプレートをいじりながら製作したことで、<html:form>タグを<form>タグのままにしていたことが原因でしたorz
テンプレートをいじりつつ、本来のHTMLタグをActionフォーム用のStrutsタグに置き換えるときには注意ってことで。
MVCモデルで知られているJSP&ServletのStrutsフレームワークですが、Contorollerの部分にあたるActionを作成しているときにちと困ったことになりました。
普通のサーブレットの場合、サーブレットの中でServletContextを呼び出すには、
ServletContext sc = getServletContext();
で良いわけですが、Strutsの場合は上記のような構文をexecuteメソッドの中に記述しても動きません。
せっかくStrutsのプラグインを用いてあるクラスをアプリケーションスコープに格納したのに取得できないなんてかなりorzな訳ですが。
ググってみたところ、上記のコードにもうひと味付けることで解決できました。
ServletContext sc = getServlet().getServletContext();
Foo bar = (Foo)sc.getAttribute("bar");
例えば、上記のコードのようにすれば、StrutsのActionサーブレットにおいてもApplicationスコープから値を取得できます。
めでたし。めでたし。