OSDN Git Service

import
[luz/luz.git] / luz2 / src / com / lavans / luz2 / http / session / RemoteHttpServletRequest.java
1 /* $Id: RemoteHttpServletRequest.java 94 2008-12-18 11:07:17Z dobashi $\r
2  * created: 2006/01/20\r
3  */\r
4 package com.lavans.luz2.http.session;\r
5 \r
6 import java.util.Iterator;\r
7 import java.util.Map;\r
8 \r
9 import javax.servlet.http.HttpServletRequest;\r
10 import javax.servlet.http.HttpServletRequestWrapper;\r
11 import javax.servlet.http.HttpSession;\r
12 \r
13 import org.apache.commons.logging.Log;\r
14 import org.apache.commons.logging.LogFactory;\r
15 \r
16 /**\r
17  * 独自にセッションの実装を行うHttpRequest.\r
18  * jsessionidのjvmRoute部分を見て、他のサーバーのセッションで\r
19  * あればそのサーバーにRemoteSessionを返すよう問い合わせる。\r
20  *\r
21  * @author dobashi\r
22  */\r
23 public class RemoteHttpServletRequest extends HttpServletRequestWrapper {\r
24         /** ロガー。debug用 */\r
25         private static Log logger = LogFactory.getLog(RemoteHttpServletRequest.class.getName());\r
26 \r
27         private HttpSession session = null;\r
28 \r
29         private static SessionServiceLocal serviceLocal = SessionServiceLocal.getInstance();\r
30         private static SessionServiceRemote serviceRemote = SessionServiceRemote.getInstance();\r
31 \r
32         /**\r
33          * @param arg0\r
34          */\r
35         public RemoteHttpServletRequest(HttpServletRequest arg0) {\r
36                 super(arg0);\r
37         }\r
38 \r
39         /**\r
40          * セッション取得\r
41          * @see javax.servlet.http.HttpServletRequest#getSession()\r
42          */\r
43         @Override\r
44         public HttpSession getSession() {\r
45                 return getSession(true);\r
46         }\r
47 \r
48         /**\r
49          * セッション取得。\r
50          * @see javax.servlet.http.HttpServletRequest#getSession(boolean)\r
51          */\r
52         @Override\r
53         public HttpSession getSession(boolean isCreate) {\r
54                 // すでに取得済みならそのセッションを返す。\r
55                 if(session!=null){\r
56                         return getCacheSession(isCreate);\r
57                 }\r
58 \r
59                 // このHttpRequestのセッションID\r
60                 session = super.getSession(false);\r
61                 if(session==null){\r
62                         // セッションが取得できないと言うことは、\r
63                         // 初回のアクセスかリモートセッション\r
64                         session = super.getSession();\r
65                         serviceLocal.setSession(session);\r
66                 }\r
67 \r
68                 // このサーバーのセッションID\r
69                 String sidSelf = session.getId();\r
70                 // リクエストされたセッションID\r
71                 String sidReq = super.getRequestedSessionId();\r
72 //logger.debug("sidSelf/Request["+ sidSelf +"/"+ sidReq +"]");\r
73                 // 上記2つが同一ならセッションをそのまま返す。\r
74                 if(sidSelf.equals(sidReq)){\r
75                         return session;\r
76                 }\r
77 \r
78                 // 自分のtomcat jvmRouteを取得。\r
79                 String jvmSelf = "";\r
80                 try {\r
81                         jvmSelf = sidSelf.split("\\.")[1];\r
82                 } catch (Exception e) {\r
83                         logger.error("tomcatのserver.xmlにjvmRouteが指定されていない");\r
84                 }\r
85                 // リクエスト元のtomcat jvmRouteを取得。\r
86                 String jvmReq="";\r
87                 try{\r
88                         // sidReq==null, sidReq=""の場合や、.tomXXのついてないセッションIDの\r
89                         // 可能性がある\r
90                         jvmReq = sidReq.split("\\.")[1];\r
91                 }catch (Exception e) {\r
92                         // 上記のエラーならローカル扱い\r
93                         sidReq = sidSelf;\r
94                         jvmReq = jvmSelf;\r
95                         logger.debug("sidReq:"+ sidReq);\r
96                 }\r
97 \r
98                 // 同じjvmでsidが異なるケース\r
99                 if(jvmReq.equals(jvmSelf)){\r
100                         if(isCreate){\r
101                                 return session;\r
102                         }\r
103 \r
104                         // 新規に作成してしまっているので破棄する。\r
105                         session.invalidate();\r
106                         return null;\r
107                 }\r
108 \r
109                 // 違うjvmならリモートのセッションサービスを使用してセッション情報を取得。\r
110                 return getRemoteSession(jvmReq, sidReq, sidSelf, isCreate);\r
111         }\r
112 \r
113 \r
114         /**\r
115          * キャッシュされているセッションが有効かどうか判定して返す。\r
116          * 無効の場合は新規作成する。\r
117          * @return\r
118          */\r
119         private HttpSession getCacheSession(boolean isCreate){\r
120                 try{\r
121                         if(serviceLocal.exists(session.getId())){\r
122                                 // ローカルで管理されているセッションなら\r
123                                 return session;\r
124                         }\r
125                 }catch (IllegalStateException e) {\r
126                 }\r
127                 // tomcat5.5.10~5.5.15ではsession.getId()でIllegalStateExceptionをthrowする。\r
128                 // tomcat5.5.9以前と5.5.16以降では無効なセッションでもgetId()では例外を生成しない。\r
129                 // したがって、前者ではinvalidateを呼ばれた後catchブロックを通ってここにくる。\r
130                 // 後者ではinvalidateの後はseviceLocal.exists()==falseとなってここにくる。\r
131                 session = super.getSession(isCreate);\r
132                 if(session!=null){\r
133                         serviceLocal.setSession(session);\r
134                 }\r
135                 return session;\r
136         }\r
137 \r
138         /**\r
139          * キャッシュされているセッションが有効かどうか判定して返す。\r
140          * 無効の場合は新規作成する。\r
141          * @return\r
142          */\r
143         private HttpSession getRemoteSession(String jvmReq, String sidReq,  String sidSelf, boolean isCreate){\r
144 \r
145                 logger.debug("session remote:"+ sidReq +"->"+ sidSelf);\r
146 \r
147                 try {\r
148                         Map<String, Object> remoteSessionAttr = serviceRemote.getRemoteSessionAttribute(jvmReq, sidReq);\r
149                         // 取得に失敗した場合\r
150                         if(remoteSessionAttr==null){\r
151                                 if(isCreate){\r
152                                         // 生成モードなら\r
153                                         return session;\r
154                                 }\r
155                                 // 新規に作成してしまっているので破棄する。\r
156                                 session.invalidate();\r
157                                 return null;\r
158                         }\r
159 \r
160                         // ローカルのセッションにリモートの属性を書き込む\r
161                         Iterator<String> attrNamesIte = remoteSessionAttr.keySet().iterator();\r
162                         StringBuffer debugStr = new StringBuffer();\r
163                         debugStr.append("session copy:");\r
164                         while(attrNamesIte.hasNext()){\r
165                                 String attrName = attrNamesIte.next();\r
166                                 // ログイン情報は新しいsidで登録\r
167                                 if(attrName.equals(sidReq)){\r
168                                         continue;\r
169                                 }\r
170                                 session.setAttribute(attrName, remoteSessionAttr.get(attrName));\r
171                                 debugStr.append("\n"+ attrName +"="+  remoteSessionAttr.get(attrName).toString());\r
172                         }\r
173                         // ログインの情報をコピー\r
174                         // visitorの場合はaccount==null\r
175                         Object account = remoteSessionAttr.get(sidReq);\r
176                         if(account!=null){\r
177                                 session.setAttribute(sidSelf, account);\r
178                                 debugStr.append("\n"+ sidReq +"="+  remoteSessionAttr.get(sidReq).toString());\r
179                         }\r
180 \r
181                         logger.debug(debugStr.toString());\r
182 \r
183                         return session;\r
184                 } catch (Exception e) {\r
185                         logger.info("remote接続失敗:", e);\r
186                 }\r
187 \r
188                 return session;\r
189         }\r
190 }\r