`

jetty对sessionId的处理分析

 
阅读更多

jetty7对sessionId的处理,首先入口在SessionHandler.java的doScope方法,jetty的源码分析可以参考这篇http://zhwj184.iteye.com/admin/blogs/1161542

 

 

 /* ------------------------------------------------------------ */
    /*
     * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
     */
    @Override
    public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException
    {
        setRequestedId(baseRequest,request);

        SessionManager old_session_manager=null;
        HttpSession old_session=null;

        try
        {
            old_session_manager = baseRequest.getSessionManager();
            old_session = baseRequest.getSession(false);

            if (old_session_manager != _sessionManager)
            {
                // new session context
                baseRequest.setSessionManager(_sessionManager);
                baseRequest.setSession(null);
            }

            // access any existing session
            HttpSession session=null;
            if (_sessionManager!=null)
            {
                session=baseRequest.getSession(false);
                if (session!=null)
                {
                    if(session!=old_session)
                    {
                        HttpCookie cookie = _sessionManager.access(session,request.isSecure());
                        if (cookie!=null ) // Handle changed ID or max-age refresh
                            baseRequest.getResponse().addCookie(cookie);
                    }
                }
                else
                {
                    session=baseRequest.recoverNewSession(_sessionManager);
                    if (session!=null)
                        baseRequest.setSession(session);
                }
            }

            if(Log.isDebugEnabled())
            {
                Log.debug("sessionManager="+_sessionManager);
                Log.debug("session="+session);
            }

            // start manual inline of nextScope(target,baseRequest,request,response);
            if (_nextScope!=null)
                _nextScope.doScope(target,baseRequest,request, response);
            else if (_outerScope!=null)
                _outerScope.doHandle(target,baseRequest,request, response);
            else 
                doHandle(target,baseRequest,request, response);
            // end manual inline (pathentic attempt to reduce stack depth)
            
        }
        finally
        {
            HttpSession session=request.getSession(false);

            if (old_session_manager != _sessionManager)
            {
                //leaving context, free up the session
                if (session!=null)
                    _sessionManager.complete(session);
                
                // Leave last session in place
                if (old_session_manager!=null )
                {
                    baseRequest.setSessionManager(old_session_manager);
                    baseRequest.setSession(old_session);
                }
            }
        }
    }

 

setRequestedId(baseRequest,request); 就是从request请求中获取sessionId的过程,首先是从cookie中获取,获取不到再从url中获取,是否设置useCookie,也可以通过配置文件配置

 

 

 

  /* ------------------------------------------------------------ */
    /** Look for a requested session ID in cookies and URI parameters
     * @param baseRequest
     * @param request
     */
    protected void setRequestedId(Request baseRequest, HttpServletRequest request)
    {
        String requested_session_id=request.getRequestedSessionId();
        if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()) || requested_session_id!=null)
            return;

        SessionManager sessionManager = getSessionManager();
        boolean requested_session_id_from_cookie=false;
        HttpSession session=null;

        // Look for session id cookie
        if (_sessionManager.isUsingCookies())
        {
            Cookie[] cookies=request.getCookies();
            if (cookies!=null && cookies.length>0)
            {
                for (int i=0;i<cookies.length;i++)
                {
                    if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
                    {
                        if (requested_session_id!=null)
                        {
                            // Multiple jsessionid cookies. Probably due to
                            // multiple paths and/or domains. Pick the first
                            // known session or the last defined cookie.
                            if (sessionManager.getHttpSession(requested_session_id)!=null)
                                break;
                        }

                        requested_session_id=cookies[i].getValue();
                        requested_session_id_from_cookie = true;
                        if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
                        
                        session=sessionManager.getHttpSession(requested_session_id);
                        if (session!=null)
                            baseRequest.setSession(session);
                    }
                }
            }
        }

        if (requested_session_id==null || session==null)
        {
            String uri = request.getRequestURI();

            String prefix=sessionManager.getSessionIdPathParameterNamePrefix();
            if (prefix!=null)
            {
                int s = uri.indexOf(prefix);
                if (s>=0)
                {   
                    s+=prefix.length();
                    int i=s;
                    while (i<uri.length())
                    {
                        char c=uri.charAt(i);
                        if (c==';'||c=='#'||c=='?'||c=='/')
                            break;
                        i++;
                    }

                    requested_session_id = uri.substring(s,i);
                    requested_session_id_from_cookie = false;
                    if(Log.isDebugEnabled())
                        Log.debug("Got Session ID "+requested_session_id+" from URL");                    
                }
            }
        }

        baseRequest.setRequestedSessionId(requested_session_id);
        baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
    }

 

  sessionId的默认参数名为:JSESSIONID

 

 

 

    /**
     * @return the session cookie name, by default "JSESSIONID".
     * @see #setSessionCookie(String)
     */
    public String getSessionCookie();
    /**
     * @return a formatted version of {@link #getSessionIdPathParameterName()}, by default
     *         ";" + sessionIdParameterName + "=", for easier lookup in URL strings.
     * @see #getSessionIdPathParameterName()
     */
    public String getSessionIdPathParameterNamePrefix();

 

 

而如果sessionId不存在,同样也是在request.getSession的时候才生成session,并且把sessionId的信息存入cookjie中

 

package org.eclipse.jetty.server;


public class Request implements HttpServletRequest{

......
 /* ------------------------------------------------------------ */
    /* 
     * @see javax.servlet.http.HttpServletRequest#getSession()
     */
    public HttpSession getSession()
    {
        return getSession(true);
    }

    /* ------------------------------------------------------------ */
    /* 
     * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
     */
    public HttpSession getSession(boolean create)
    {
        if (_sessionManager==null && create)
            throw new IllegalStateException("No SessionManager");
        
        if (_session != null && _sessionManager!=null && _sessionManager.isValid(_session))
            return _session;
        
        _session=null;
        
        String id=getRequestedSessionId();
        
        if (id != null && _sessionManager!=null)
        {
            _session=_sessionManager.getHttpSession(id);
            if (_session == null && !create)
                return null;
        }
        
        if (_session == null && _sessionManager!=null && create )
        {
            _session=_sessionManager.newHttpSession(this);
            HttpCookie cookie=_sessionManager.getSessionCookie(_session,getContextPath(),isSecure());
            if (cookie!=null)
                _connection.getResponse().addCookie(cookie);
        }
        
        return _session;
    }
......
}

 

 

我们再看下如果session不存在,则会通过_sessionManager.newHttpSession(this);创建一个,创建过程如下:

 

 /* ------------------------------------------------------------ */
    /**
     * Create a new HttpSession for a request
     */
    public HttpSession newHttpSession(HttpServletRequest request)
    {
        Session session=newSession(request);
        session.setMaxInactiveInterval(_dftMaxIdleSecs);
        addSession(session,true);
        return session;
    }
  /* ------------------------------------------------------------ */
  //HashSessionManager的实现
    @Override
    protected AbstractSessionManager.Session newSession(HttpServletRequest request)
    {
        return new HashedSession(request);
    }

/**
         * Session from a request.
         * 
         * @param request
         */
//JDBCSESSIONManager的实现
        protected Session (HttpServletRequest request)
        {
            super(request);   
            _data = new SessionData(_clusterId,_attributes);
            if (_dftMaxIdleSecs>0)
                _data.setMaxIdleMs(_dftMaxIdleSecs*1000);
            _data.setCanonicalContext(canonicalize(_context.getContextPath()));
            _data.setVirtualHost(getVirtualHost(_context));
            _data.setExpiryTime(_maxIdleMs < 0 ? 0 : (System.currentTimeMillis() + _maxIdleMs));
        }

 

而通过request创建对应SESSIONID的,sessionId分为两部分:clusterId和nodeId, nodeId就是SESSIONID

 

 protected Session(HttpServletRequest request)
        {
            _newSession=true;
            _created=System.currentTimeMillis();
            _clusterId=_sessionIdManager.newSessionId(request,_created);
            _nodeId=_sessionIdManager.getNodeId(_clusterId,request);
            _accessed=_created;
            _lastAccessed=_created;
            _requests=1;
            Log.debug("new session & id "+_nodeId+" "+_clusterId);
        }

 

 

 

JDBC的getNodeId

    /** 
     * Get the session id, including this node's id as a suffix.
     * 
     * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest)
     */
    public String getNodeId(String clusterId, HttpServletRequest request)
    {
        if (_workerName!=null)
            return clusterId+'.'+_workerName;

        return clusterId;
    }
 

Hash的getNodeId

    /* ------------------------------------------------------------ */
    /** Get the session ID with any worker ID.
     * 
     * @param clusterId
     * @param request
     * @return sessionId plus any worker ID.
     */
    public String getNodeId(String clusterId,HttpServletRequest request) 
    {
        // used in Ajp13Parser
        String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute");
        if (worker!=null) 
            return clusterId+'.'+worker; 
        
        if (_workerName!=null) 
            return clusterId+'.'+_workerName;
       
        return clusterId;
    }

 

jetty是做好了集群sessionId生成的配置。

 

15
52
分享到:
评论

相关推荐

    Jetty权威指南.pdf

    - **高性能**:Jetty采用异步处理机制,能够高效处理大量并发连接,尤其适用于高负载的Web应用。 - **灵活可定制**:Jetty通过模块化设计,用户可以根据实际需求选择加载必要的组件,避免不必要的功能带来额外负担。...

    Jetty中文手册

    如何配置会话ID(Session IDs) 如何序列化会话(Session) 如何重定向或移动应用(Context) 如何让一个应用响应一个特定端口 使用JNDI 使用JNDI 在JNDI中配置数据源(DataSource) 内嵌Jetty服务器 内嵌Jetty教程 ...

    基于jetty8 websocket的例子

    在本文中,我们将深入探讨如何使用Jetty 8实现WebSocket技术来构建一个实时通信的聊天工具。WebSocket协议是一种在客户端和服务器之间建立长连接的协议,它为双向通信提供了低延迟、高效的解决方案,特别适合实时...

    初学SpringSession讲义大全.docx

    2. 使用 URL 重写:如果客户端的浏览器禁用了 Cookie,可以使用 URL 重写的技术来进行 session 会话跟踪,即每次 HTTP 交互,URL 后面都会被附加上一个诸如 sessionId=xxxxx 这样的参数,服务端据此来识别客户端是谁...

    Session(实例)

    在Eclipse中操作Session,首先需要配置服务器环境,如Tomcat或Jetty。Eclipse提供了内置的服务器支持,可以在"Window" -&gt; "Preferences" -&gt; "Server"中进行设置。选择合适的服务器并添加到工作空间,然后右键点击...

    session.会话实例源码

    源码分析可以让我们了解Session是如何在内部管理这些操作的,包括Session ID的生成、数据的序列化与反序列化,以及超时机制。 **5. 实例:使用Session进行状态管理** 以下是一个简单的Java Servlet示例,展示了如何...

    session和memcached共享需要的jar

    4. **其他依赖库**:根据所选的Memcached Session Manager和配置,可能还需要一些其他的库,如`slf4j-api-x.x.x.jar`,`log4j-over-slf4j-x.x.x.jar`等日志处理库,以及可能的容器特定库(如Tomcat,Jetty等)。...

    httpSession

    6. **源码解析**:深入到具体的Web容器(如Tomcat、Jetty)的源代码中,理解它们如何处理session的创建、存储和销毁。 7. **工具使用**:可能介绍了一些辅助管理session的工具或库,如使用浏览器开发者工具查看...

    jsp学生管理系统源码+分析

    通过以上分析,我们可以看出JSP学生管理系统是一个综合运用了多种技术和设计模式的项目,它不仅涉及Web前端展示,还包括后端数据处理和业务逻辑实现。对于学习和理解JSP技术及其在实际项目中的应用,这样的源码分析...

    day18 监听器 统计在线人数,定时销毁超时session,钝化活化session,在线列表显示和踢人功能防止用户自动登录,在线支付

    实现上述功能可能需要对Servlet、JSP、Spring MVC等框架有深入理解,同时也可能用到如Eclipse、IntelliJ IDEA等开发工具,以及Apache Tomcat、Jetty等应用服务器。 以上知识点涵盖了Web应用中的用户管理、session...

    一个前后端分离的简易进销存后台管理系统

    客户端在后续请求中携带这个Session ID,服务器通过Session ID识别用户,保持登录状态。 4. **基于资源URL的权限控制**:这是一种常见的访问控制策略,它根据用户角色和资源URL的关系来决定用户是否可以访问特定的...

    JAVA EE知识串讲

    Session在服务器端维护,每个用户会被分配一个唯一的Session ID,这个ID会被发送到客户端(通常是通过Cookie)。当用户发送请求时,携带这个Session ID,服务器就能识别出是哪个用户的请求,从而保持用户的登录状态...

    登陆登出

    5. **源码分析**:博主可能详细解释了每个类和方法的功能,分析了代码逻辑,例如如何处理登录失败的情况,如何防止SQL注入,以及如何确保会话的安全性等。 6. **工具使用**:可能会提到使用某些开发工具,如Eclipse...

    基于Java Web(Servlet)的电影售票管理系统.zip

    Session对象在服务器端创建,每个用户对应一个唯一的session ID,用于区分不同的会话。 6. **安全性**:在毕设项目中,系统的安全性不容忽视。可能涉及的措施包括输入验证,防止SQL注入;使用HTTPS协议确保数据传输...

    javaweb的投票系统.zip

    系统需要防范SQL注入攻击、XSS跨站脚本攻击,并对敏感数据(如用户密码)进行加密处理。 8. **异常处理**:良好的异常处理机制可以确保系统在遇到问题时能够优雅地处理错误,提供友好的错误提示,同时方便调试和...

    基于Servlet的图书管理系统.zip

    8. **会话管理**:为了跟踪用户的操作,系统可能使用了session技术,为每个用户创建唯一的session ID,存储用户的登录状态和其他相关信息。 9. **安全机制**:图书管理系统可能会有权限控制,比如登录验证、角色...

    Java 聊天室

    每个用户都有一个唯一的session ID,服务器通过这个ID识别用户并保持其会话状态。 6. **AJAX异步更新**:为了让聊天室有更流畅的用户体验,开发者可能采用了AJAX(Asynchronous JavaScript and XML)技术。通过AJAX...

    jsp+servlet实现的CRM管理系统

    用户登录后,服务器会创建一个 session 并存储用户信息,后续请求会通过 session ID 验证用户身份。 6. **安全措施**: 系统可能包含了防止 SQL 注入、XSS 攻击的安全措施,如使用预编译 SQL 语句、对用户输入进行...

    jsp+servlet聊天源码

    - 用户每次发送消息时,都会携带session ID,以便服务器识别用户身份。 5. **数据传输**: - 聊天消息通常以JSON或XML格式在网络上传输,这些格式轻量且易于解析。 - 消息可能包含发送者、接收者、时间戳和消息...

Global site tag (gtag.js) - Google Analytics