FM牛鍵屋本舗

プログラマ(弱)の日々精進系ブログ

jsessionidとsastrutsのタグライブラリの罠と戦ったよ!!

外部オープンにオープンする機能を書いていて、どこからリンクを設定するかが未定だったのでとりあえずURL直叩きで動作確認を行っていました。その中で、他機能の詳細画面(こちらも公開)へ飛ばす処理があったのですが、これがまた特定条件下の場合に404エラーに。

事象自体は割りとすぐにあたりがついて、「ブラウザのキャッシュクリア」後に「初回の詳細画面リクエスト」が失敗。理由はURLに;jsessionidがくっついていたから。 というよりも、パラメータとなる識別子をURLに含む、いわゆるRestっぽいURIで実現しようとしていたのですが、そのパラメータが;jsessionidでかき消されているというか。 ちなみに、hidden項目でURLをHTML上に保持して、クリックイベント着火で対象のSEQ取得、location.hrefで遷移、という形をとっていました。

色々調べてみると、TomcatのHttpServletResponseのencodeURLの実装はデフォルトで、「CookieでセッションIDをやり取りしていない場合はURLリライティングでjsessionidを付加する」みたいな形になっている様子。

いやでも明示的に呼んでないぞそのメソッド…と途方に暮れていたのですが、呼んでましたよSAStrutsのカスタムタグで…。

f:url()

この記述は下記のurlメソッドを呼び出しています。 ざっくりいうと、コンテキストパスなどを含めたURLを補完してくれるメソッドです。

S2Functions

動的解析がうまくいかなかったのでとりあえずの推測になりますが、

  1. URL直指定でアクションメソッドを呼び出す
  2. 当然、cookieのjsessionidは指定されていない
  3. JSPコンパイル時、;jsessionidを付加したURLをHTMLを出力 1. レスポンスヘッダーでcookieにjsessionid書き込み。
  4. ;jsessionid=XXXのURLにseqくっつけて遷移
  5. そんなURLないと怒られる

ということだったんだろうなあ。

対象文字を置換にすることで対応しました。

他の方法としては * PGRパターンっぽくリロードする * URLの出力方法を変更する * URLのパラメーターをやめてGET/POSTでのパラメータ渡しにする とかがあるのかな。