1 /* $Id: RemoteHttpServletRequest.java 94 2008-12-18 11:07:17Z dobashi $
\r
2 * created: 2006/01/20
\r
4 package com.lavans.luz2.http.session;
\r
6 import java.util.Iterator;
\r
7 import java.util.Map;
\r
9 import javax.servlet.http.HttpServletRequest;
\r
10 import javax.servlet.http.HttpServletRequestWrapper;
\r
11 import javax.servlet.http.HttpSession;
\r
13 import org.apache.commons.logging.Log;
\r
14 import org.apache.commons.logging.LogFactory;
\r
17 * 独自にセッションの実装を行うHttpRequest.
\r
18 * jsessionidのjvmRoute部分を見て、他のサーバーのセッションで
\r
19 * あればそのサーバーにRemoteSessionを返すよう問い合わせる。
\r
23 public class RemoteHttpServletRequest extends HttpServletRequestWrapper {
\r
25 private static Log logger = LogFactory.getLog(RemoteHttpServletRequest.class.getName());
\r
27 private HttpSession session = null;
\r
29 private static SessionServiceLocal serviceLocal = SessionServiceLocal.getInstance();
\r
30 private static SessionServiceRemote serviceRemote = SessionServiceRemote.getInstance();
\r
35 public RemoteHttpServletRequest(HttpServletRequest arg0) {
\r
41 * @see javax.servlet.http.HttpServletRequest#getSession()
\r
44 public HttpSession getSession() {
\r
45 return getSession(true);
\r
50 * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
\r
53 public HttpSession getSession(boolean isCreate) {
\r
54 // すでに取得済みならそのセッションを返す。
\r
56 return getCacheSession(isCreate);
\r
59 // このHttpRequestのセッションID
\r
60 session = super.getSession(false);
\r
62 // セッションが取得できないと言うことは、
\r
63 // 初回のアクセスかリモートセッション
\r
64 session = super.getSession();
\r
65 serviceLocal.setSession(session);
\r
69 String sidSelf = session.getId();
\r
71 String sidReq = super.getRequestedSessionId();
\r
72 //logger.debug("sidSelf/Request["+ sidSelf +"/"+ sidReq +"]");
\r
73 // 上記2つが同一ならセッションをそのまま返す。
\r
74 if(sidSelf.equals(sidReq)){
\r
78 // 自分のtomcat jvmRouteを取得。
\r
79 String jvmSelf = "";
\r
81 jvmSelf = sidSelf.split("\\.")[1];
\r
82 } catch (Exception e) {
\r
83 logger.error("tomcatのserver.xmlにjvmRouteが指定されていない");
\r
85 // リクエスト元のtomcat jvmRouteを取得。
\r
88 // sidReq==null, sidReq=""の場合や、.tomXXのついてないセッションIDの
\r
90 jvmReq = sidReq.split("\\.")[1];
\r
91 }catch (Exception e) {
\r
95 logger.debug("sidReq:"+ sidReq);
\r
99 if(jvmReq.equals(jvmSelf)){
\r
104 // 新規に作成してしまっているので破棄する。
\r
105 session.invalidate();
\r
109 // 違うjvmならリモートのセッションサービスを使用してセッション情報を取得。
\r
110 return getRemoteSession(jvmReq, sidReq, sidSelf, isCreate);
\r
115 * キャッシュされているセッションが有効かどうか判定して返す。
\r
119 private HttpSession getCacheSession(boolean isCreate){
\r
121 if(serviceLocal.exists(session.getId())){
\r
122 // ローカルで管理されているセッションなら
\r
125 }catch (IllegalStateException e) {
\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
133 serviceLocal.setSession(session);
\r
139 * キャッシュされているセッションが有効かどうか判定して返す。
\r
143 private HttpSession getRemoteSession(String jvmReq, String sidReq, String sidSelf, boolean isCreate){
\r
145 logger.debug("session remote:"+ sidReq +"->"+ sidSelf);
\r
148 Map<String, Object> remoteSessionAttr = serviceRemote.getRemoteSessionAttribute(jvmReq, sidReq);
\r
150 if(remoteSessionAttr==null){
\r
155 // 新規に作成してしまっているので破棄する。
\r
156 session.invalidate();
\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
170 session.setAttribute(attrName, remoteSessionAttr.get(attrName));
\r
171 debugStr.append("\n"+ attrName +"="+ remoteSessionAttr.get(attrName).toString());
\r
174 // visitorの場合はaccount==null
\r
175 Object account = remoteSessionAttr.get(sidReq);
\r
177 session.setAttribute(sidSelf, account);
\r
178 debugStr.append("\n"+ sidReq +"="+ remoteSessionAttr.get(sidReq).toString());
\r
181 logger.debug(debugStr.toString());
\r
184 } catch (Exception e) {
\r
185 logger.info("remote接続失敗:", e);
\r