「Tomcat」と一致するもの

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のログインシステムを作る上で結構役に立ちそうです。
あるユーザでログイン後、セッションが切れる前にブラウザのログインページに戻って別のユーザでログインすると、前のユーザのログイン情報が残って危険な場合も考えられます。そのような問題も防げそうですね。
向こうの記事で十分説明されているので、敢えてこちらは講評だけにしておきます。

Hibernateを用いてシステム開発をしていると、確かに便利なんですが微妙に重いな〜なんて感じます。
Hibernateの公式サイトから必要なファイルをダウンロードし、説明書を読んで必須(Required)と書かれているファイルを導入しても、果たして、それらが全て必要なのか微妙なところです。

そこでググってみたところ、
ギジュツメモ - TomcatでHibernateを動かすとき最低限追加設置が必要なJarを見つけました。

自ら必要だろうと思って設置したファイルより大分削減できそうな感じです。
「Hibernate関連のJARファイル多すぎじゃね?」って思える人は是非参考にして下さい。

StrutsからServletContextクラスを取得するには

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スコープから値を取得できます。

めでたし。めでたし。

JSPでEL式が使えない場合の対策

久々のblogネタを投稿してみる。

最近、JSPをよくいじっているわけですが、JSPにはJSTL(JSP Standard Tag Library)の標準タグライブラリとEL(Expression Language)式が使えると便利かなと思いました。

JSTLとは、JSPで使えるカスタムタグライブラリの一つで、JakartaプロジェクトによりJSPで便利なタグをひとまとめにしたライブラリです。
その中でよく使われるのがCoreタグライブラリとEL式です。

JSTLに関する詳しい解説はKishida's SITE 〜 Java入門講座 - JSTL(標準タグライブラリ)Javaの道(Java入門・リファレンス) - Javaの道:Taglibs(2.Standard Taglibsの概要)に丸投げしますが、今回はそのEL式が使えない場合のお話。

JSTLを使うには、JakartaプロジェクトのページからJSTLのファイルをダウンロードし、サーブレットコンテナ(Tomcat)のWEB-INF\libに「standard.jar」と「jstl.jar」を設置してやることで完了です
...って思ってたんですよ。

ええ、これだけでも<c:out>や<c:forEach>などのタグライブラリは動くんです。
でもね、でもね。
これだとEL式が動いてくれなかったんですねorz

${true}がそのまま「${true}」って表示されちゃうんです( ̄□ ̄;)!!

そこで色々ググってみたところ、似たような問題で悩んでいる方はいました。

wakasa.org - ●Tomcat5.5でtaglib内でEL式が動かない

ただ、俺の場合これだけじゃありませんでした。
「standard.jar」や「jstl.jar」を「WEB-INF\lib」に設置するだけではなく、「web.xml」にの設定も追加しましょう。

Tomcat5の新機能第2回:EL式とタグファイルに書かれていますが、

<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/tld/c.tld</taglib-location>
</taglib>

を忘れると、JSTLが使えるのにEL式が使えないという不思議な体験ができます。
結局のところ俺がきちんと説明書見てなかったからこんな事態になっただけなんですけどねorz

というわけで、自分の備忘録とともに同じ問題で苦しんでいる人の助けになれば良いかなと思います。

久々にblogを書く機会がバグへの対処とはorz

2006年08月27日に投稿した「sendRedirectで日本語文字のURLが入っている場合の対処」の記事の方法だとURLによりExceptionが発生してしまうようです。
URL中に半角スペースを含むURLの場合RFC2396に違反するため、エスケープしなければいけません。
実はJ2SDK 1.4までは半角スペースを含むURLであってもURIクラス等でインスタンスを作成可能でしたが、JDK 5.0からはRFC2396に従いあらかじめエスケープしなければいけなくなったようです。

String strUrl = "https://traincat.net/blog/neko/電車猫の blog/日本語 ファイル名.doc".replace(" ","%20");
URI uri = new URI(strUrl);
response.sendRedirect(uri.toASCIIString());

この様にすれば、半角スペースが「%20」と変換されるのでURISyntaxExceptionやMalformedURLExceptionなしにURIクラスのインスタンスを作成できそうです。

めでたしめでたし。


・参考文献:
SMG-Java トラブルシューティング
 + JDK1.3で動作していたプログラムをJDK1.4で実行したところ、Naming.bind()で例外が発生しました。