Apache-Tomcatのプロキシ設定を変更したらsessionがとれなくなった

Javaアプリでsessionスコープに保存したPOJOを取得できずにハマったときのメモ。

構成

  • アプリのフレームワークはSpring3。通常のServletアプリケーション。
  • 前段のWebサーバにApache、JavaアプリのコンテナとしてTomcatを用いて、両者の連携はmod_proxy_ajpを利用。

やりたいこと

ふつうにsessionスコープに保存したobjectを別のパスで取得する。
イメージとしては下の感じ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

package hoge.foo.contoroller


import hoge.foo.LoginForm

@RequestMapping(value="/user")
public class UserController{

private static final String SESSION_FORM_NAME = "user_input_data"

/**
* ログイン
*/
@RequestMapping(value="/login", method=RequestMethod.POST)
public String login(
@Valid @ModelAttribute LoginForm form,
BindingResult result,
HttpServletRequest request,
Model model) {

if(result.hasError){
return "login"; //入力エラー
}

// ログインに関する処理

request.getSession().setAttribute(SESSION_FORM_NAME, form); //session格納
return "dashboard";
}



/**
* セッションのユーザデータを参照して編集画面を表示する
*/
@RequestMapping(value="/edit", method=RequestMethod.GET)
public String editView(
HttpServletRequest request,
Model model) {

LoginForm form = request.getSession().getAttribute(SESSION_FORM_NAME);

if(form == null) {
return "login"; // ログイン画面に戻る
}
//後続処理

return "edit";
}

}

sessionからデータがとれない!

/user/editを叩いても常に/user/loginに遷移する。つまりform == nullが常にtrueとなってしまっている。
念のためデバッガでステップ実行してみても、やはりformがnullである。

セッションタイムアウトの設定やSpringでのセッションの利用方法など、あらゆるドキュメントを確認するも、
まったく解決の糸口が掴めない。なんだ….なにが悪いっていうんだ….!!

あっ!

ここで、前日の開発で別のコンテキストパスで動作させるために、server.xmlとhttpd.confのProxyPassを変更したことを思い出す。
httpd.confはこんな感じ。

1
ProxyPassMatch  /  ajp://localhost:8009/spring/

そしてJSESSIONIDがクッキーに保存されていて、クッキーにはPathがあって……!?

あれ…?もしかしてセッションIDのクッキーのPath、ずれてるんじゃない…?

とりあえずリバースプロキシの設定を戻し、ApacheとTomcatを再起動。

1
ProxyPassMatch  /  ajp://localhost:8009/

##あー、とれたわー。sessionから普通にobject取得できたわー。

ちなみにリバースプロキシでパス階層がずれる場合は、ProxyPassReverseCookiePathディレクティブを使うらしいです。