博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
request.getSession(true/false)的区别
阅读量:5753 次
发布时间:2019-06-18

本文共 7677 字,大约阅读时间需要 25 分钟。

javax.servlet.http.HttpServletRequest接口有两个方法:getSession(boolean)和getSession()。

具体什么区别,跟踪源码分析下,先摆出结论:
request.getSession(true):获取session,如果session不存在,就新建一个。
reqeust.getSession(false)获取session,如果session不存在,则返回null。
Debug时,查看HttpServletRequest接口的实现类为RequestFacade。
RequestFacade.png
使用Idea查看RequestFacade的代码实现,可以看出是通过Facade外观模式对org.apache.catalina.connector.Request进行了封装。
继续看getSession()的源码,其实是调用了getSession(true)。具体是调用了request.getSession(create)。

@Overridepublic HttpSession getSession(boolean create) {    if (request == null) {        throw new IllegalStateException(                        sm.getString("requestFacade.nullRequest"));    }    if (SecurityUtil.isPackageProtectionEnabled()){        return AccessController.            doPrivileged(new GetSessionPrivilegedAction(create));    } else {        return request.getSession(create);    }}@Overridepublic HttpSession getSession() {    if (request == null) {        throw new IllegalStateException(                        sm.getString("requestFacade.nullRequest"));    }    // 直接调用getSession(true)    return getSession(true);}

进入到Request.getSession(boolean),根据注释看出,create为true时,如果HttpSession不存在,会创建一个新的HttpSession。

/**     * @return the session associated with this Request, creating one     * if necessary and requested.     *     * @param create Create a new session if one does not exist     */    @Override    public HttpSession getSession(boolean create) {        Session session = doGetSession(create);        if (session == null) {            return null;        }        return session.getSession();    }

继续进入到doGetSession(boolean create)方法,继续分析。

protected Session doGetSession(boolean create) {        // There cannot be a session if no context has been assigned yet        Context context = getContext();        if (context == null) {            return (null);        }        // Return the current session if it exists and is valid        // 如果当前session存在且有效,返回当前session        if ((session != null) && !session.isValid()) {            session = null;        }        if (session != null) {            return (session);        }        // Return the requested session if it exists and is valid        // 这里有读写锁控制并发        Manager manager = context.getManager();        if (manager == null) {            return (null);      // Sessions are not supported        }        if (requestedSessionId != null) {            try {                session = manager.findSession(requestedSessionId);            } catch (IOException e) {                session = null;            }            if ((session != null) && !session.isValid()) {                session = null;            }            if (session != null) {                session.access();                return (session);            }        }        // Create a new session if requested and the response is not committed        // create为false时,返回null;create为true时创建一个新的session        if (!create) {            return (null);        }        if (response != null                && context.getServletContext()                        .getEffectiveSessionTrackingModes()                        .contains(SessionTrackingMode.COOKIE)                && response.getResponse().isCommitted()) {            throw new IllegalStateException(                    sm.getString("coyoteRequest.sessionCreateCommitted"));        }        // Re-use session IDs provided by the client in very limited        // circumstances.        String sessionId = getRequestedSessionId();        if (requestedSessionSSL) {            // If the session ID has been obtained from the SSL handshake then            // use it.        } else if (("/".equals(context.getSessionCookiePath())                && isRequestedSessionIdFromCookie())) {            /* This is the common(ish) use case: using the same session ID with             * multiple web applications on the same host. Typically this is             * used by Portlet implementations. It only works if sessions are             * tracked via cookies. The cookie must have a path of "/" else it             * won't be provided for requests to all web applications.             *             * Any session ID provided by the client should be for a session             * that already exists somewhere on the host. Check if the context             * is configured for this to be confirmed.             */            if (context.getValidateClientProvidedNewSessionId()) {                boolean found = false;                for (Container container : getHost().findChildren()) {                    Manager m = ((Context) container).getManager();                    if (m != null) {                        try {                            if (m.findSession(sessionId) != null) {                                found = true;                                break;                            }                        } catch (IOException e) {                            // Ignore. Problems with this manager will be                            // handled elsewhere.                        }                    }                }                if (!found) {                    sessionId = null;                }            }        } else {            sessionId = null;        }        session = manager.createSession(sessionId);        // Creating a new session cookie based on that session        if (session != null                && context.getServletContext()                        .getEffectiveSessionTrackingModes()                        .contains(SessionTrackingMode.COOKIE)) {            Cookie cookie =                ApplicationSessionCookieConfig.createSessionCookie(                        context, session.getIdInternal(), isSecure());            response.addSessionCookieInternal(cookie);        }        if (session == null) {            return null;        }        session.access();        return session;    }

StandardContext跟session没有啥关系,就是学习下StandardContext的源码及ReentrantReadWriteLock。

@Override    public Manager getManager() {        Lock readLock = managerLock.readLock();        readLock.lock();        try {            return manager;        } finally {            readLock.unlock();        }    }    @Override    public void setManager(Manager manager) {        Lock writeLock = managerLock.writeLock();        writeLock.lock();        Manager oldManager = null;        try {            // Change components if necessary            oldManager = this.manager;            if (oldManager == manager)                return;            this.manager = manager;            // Stop the old component if necessary            if (oldManager instanceof Lifecycle) {                try {                    ((Lifecycle) oldManager).stop();                    ((Lifecycle) oldManager).destroy();                } catch (LifecycleException e) {                    log.error("StandardContext.setManager: stop-destroy: ", e);                }            }            // Start the new component if necessary            if (manager != null) {                manager.setContext(this);            }            if (getState().isAvailable() && manager instanceof Lifecycle) {                try {                    ((Lifecycle) manager).start();                } catch (LifecycleException e) {                    log.error("StandardContext.setManager: start: ", e);                }            }        } finally {            writeLock.unlock();        }        // Report this property change to interested listeners        support.firePropertyChange("manager", oldManager, manager);    }

结论:

request.getSession(true):获取session,如果session不存在,就新建一个。
reqeust.getSession(false)获取session,如果session不存在,则返回null。

转载于:https://www.cnblogs.com/Candies/p/10635414.html

你可能感兴趣的文章
项目遇到的问题
查看>>
Hadoop完全分布式集群搭建遇到的一些问题
查看>>
Netty之EventLoop
查看>>
Redis 数据类型
查看>>
Druid 入门 数据导入
查看>>
MySQL 5.7 新特性之 JSON
查看>>
Linux添加/删除用户和用户组
查看>>
kickstart配置文件适配 vlan 场景应用
查看>>
hyperkube (v1.6.2, v1.7.2)部署所需各镜像版本搭配
查看>>
Hibernate<二> - Session
查看>>
Linux 磁盘与磁盘分区
查看>>
JedisConnectionFactory 和 JedisPool
查看>>
.Net MVC 的项目的一些小坑
查看>>
Scala入门-大数据云计算下的开发语言
查看>>
如何自学人工智能?
查看>>
阿里云 oss JavaScript客户端签名文件上传 vue2.0
查看>>
快速掌握阿里云 E-MapReduce
查看>>
Mysql索引原理浅析
查看>>
offsetWidth,clientWidth,width,scrollWidth之间的区别
查看>>
生辰八字取名的方法
查看>>