tomcat(jboss-web)實現所有二級域名共用sessionID

一. 需求.

    我們公司要對自己的各個網站進行數據採集,想了解一個用戶在我們網站的整個瀏覽軌跡,但是我們每個二級域名都對應自己的項目,也就是說對應自己的jsessionid,我們無法把這些數據關聯起來,所以想到讓所有的二級域名都公用一個jsessionid,這樣用戶的整個瀏覽數據我們就都能得到了。


二. 開發。

    需要對tomcat(jboss-web)的源碼進行修改,修改的地方有兩處。

    1.org.apache.catalina.connector.Request的configureSessionCookie方法

 /**
     * Configures the given JSESSIONID cookie.
     *
     * @param cookie The JSESSIONID cookie to be configured
     */
    protected void configureSessionCookie(TomcatCookie cookie) {
        cookie.setMaxAge(-1);
        if (context.getSessionCookie().getPath() != null) {
            cookie.setPath(context.getSessionCookie().getPath());
        } else {
            String contextPath = context.getEncodedPath();
            if ("".equals(contextPath)) {
                contextPath = "/";
            }
            cookie.setPath(contextPath);
        }
        if (context.getSessionCookie().getComment() != null) {
            cookie.setComment(context.getSessionCookie().getComment());
        }
        if (context.getSessionCookie().getDomain() != null) {
            cookie.setDomain(context.getSessionCookie().getDomain());
        }
        if (context.getSessionCookie().isHttpOnly()) {
            cookie.setHttpOnly(true);
        }
        
        cookie.setPath("/");
        cookie.setDomain(System.getProperty("cookieDomain")); 
        
        if (context.getSessionCookie().isSecure()) {
            cookie.setSecure(true);
        } else if (isSecure()) {
            cookie.setSecure(true);
        }
    }

添加的代碼是  

cookie.setPath("/");
cookie.setDomain(System.getProperty("cookieDomain"));

      2.在編譯好的tomcat中修改conf下的catalina.properties

添加cookieDomain變量 cookieDomain=.cdeledu.com


三.原理

    tomcat如何讀取客戶端的jsessionid

        向tomcat請求過程中,需要訪問org.apache.catalina.connector.CoyoteAdapter的sevice方法,裏面調用了postParseRequest方法,這個方法就是主要解析客戶端的jsessionid,其中parseSessionId主要是分析url裏的jessionID,parseSessionCookiesId這個是分析cookie中的jsessionid

代碼如下:

從url獲得jsesionid

    /**
     * Parse session id in URL.
     */
    protected void parseSessionId(org.apache.coyote.Request req, Request request) {

        ByteChunk uriBC = req.requestURI().getByteChunk();
        //math的值爲:";jsessionid=" ,判斷url中是否有這個字符串
        int semicolon = uriBC.indexOf(match, 0, match.length(), 0);
        //如果有解析,並賦值給request(org.apache.catalina.connector.Request)
        if (semicolon > 0) {

            // Parse session ID, and extract it from the decoded request URI
            int start = uriBC.getStart();
            int end = uriBC.getEnd();

            int sessionIdStart = semicolon + match.length();
            int semicolon2 = uriBC.indexOf(';', sessionIdStart);
            if (semicolon2 >= 0) {
                request.setRequestedSessionId
                    (new String(uriBC.getBuffer(), start + sessionIdStart, 
                            semicolon2 - sessionIdStart));
                // Extract session ID from request URI
                byte[] buf = uriBC.getBuffer();
                for (int i = 0; i < end - start - semicolon2; i++) {
                    buf[start + semicolon + i] 
                        = buf[start + i + semicolon2];
                }
                uriBC.setBytes(buf, start, end - start - semicolon2 + semicolon);
            } else {
                request.setRequestedSessionId
                    (new String(uriBC.getBuffer(), start + sessionIdStart, 
                            (end - start) - sessionIdStart));
                uriBC.setEnd(start + semicolon);
            }
            request.setRequestedSessionURL(true);

        } else {
            request.setRequestedSessionId(null);
            request.setRequestedSessionURL(false);
        }

    }

從cookie中獲取

    /**
     * Parse session id in URL.
     */
    protected void parseSessionCookiesId(org.apache.coyote.Request req, Request request) {

        // Parse session id from cookies 獲取request中的cookie
        Cookies serverCookies = req.getCookies();
        int count = serverCookies.getCookieCount();
        if (count <= 0)
            return;

        for (int i = 0; i < count; i++) {
            ServerCookie scookie = serverCookies.getCookie(i);
            //判斷cookie中有name爲jsessionid的,
            //有就賦值給request(org.apache.catalina.connector.Request)
            if (scookie.getName().equals(Globals.SESSION_COOKIE_NAME)) {
                // Override anything requested in the URL
                if (!request.isRequestedSessionIdFromCookie()) {
                    // Accept only the first session id cookie
                    convertMB(scookie.getValue());
                    request.setRequestedSessionId
                        (scookie.getValue().toString());
                    request.setRequestedSessionCookie(true);
                    request.setRequestedSessionURL(false);
                    if (log.isDebugEnabled())
                        log.debug(" Requested cookie session id is " +
                            request.getRequestedSessionId());
                } else {
                    if (!request.isRequestedSessionIdValid()) {
                        // Replace the session id until one is valid
                        convertMB(scookie.getValue());
                        request.setRequestedSessionId
                            (scookie.getValue().toString());
                    }
                }
            }
        }

    }

由於咱們寫到的是主域下,所以在tomcat中能獲得這個cookie(tomcat中能獲得的cookie的範圍爲自己域名下和主域下的)。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章