【原文链接】:https://blog.tecchen.tech ,博文同步发布到博客园。

由于精力有限,对文章的更新可能不能及时同步,请点击上面的原文链接访问最新内容。

欢迎访问我的个人网站:https://www.tecchen.tech

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

具体什么区别,跟踪源码分析下,先摆出结论:

request.getSession(true):获取session,如果session不存在,就新建一个。

reqeust.getSession(false)获取session,如果session不存在,则返回null。

Debug时,查看HttpServletRequest接口的实现类为RequestFacade。



使用Idea查看RequestFacade的代码实现,可以看出是通过Facade外观模式对org.apache.catalina.connector.Request进行了封装。

继续看getSession()的源码,其实是调用了getSession(true)。具体是调用了request.getSession(create)。

@Override
public 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);
}
} @Override
public 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。

request.getSession(true/false)的区别的更多相关文章

  1. 【转】于request.getSession(true/false/null)的区别

    http://blog.csdn.net/gaolinwu/article/details/7285783 关于request.getSession(true/false/null)的区别 一.需求原 ...

  2. 关于request.getsession(true|false)

    request.getSession(true):若存在会话则返回该会话,否则新建一个会话.request.getSession(false):若存在会话则返回该会话,否则返回NULL

  3. 转:request.getSession(true)和request.getSession(false)的区别

    1.转自:http://wenda.so.com/q/1366414933061950?src=150 概括: request.getSession(true):若存在会话则返回该会话,否则新建一个会 ...

  4. request.getSession(true)和request.getSession(false)的区别

    request.getSession(true)和request.getSession(false)的区别   request.getSession(true):若存在会话则返回该会话,否则新建一个会 ...

  5. 如何获得 request, "request.getSession(true).setAttribute("a",a);"与“request.setAttribute("a",a);”区别

    protected ServletContext getServletContext() { return ServletActionContext.getServletContext();} pro ...

  6. request.getSession()、reqeust.getSession(false)和request.getSession(true)

    getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象 getSession(false):当session存在 ...

  7. 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)--转

    出处:http://blog.csdn.net/xxd851116/archive/2009/06/25/4296866.aspx [前面的话] 在网上经常看到有人对request.getSessio ...

  8. 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)

    本文属于本人原创,转载请注明出处:http://blog.csdn.net/xxd851116/archive/2009/06/25/4296866.aspx [前面的话] 在网上经常看到有人对req ...

  9. request.getSession()几种获取情况之间的差异

    一.三种情况如下 HttpSession session = request.getSession(); HttpSession session = request.getSession(true); ...

随机推荐

  1. [SoapUI]怎样保存response到本地文件夹

    def myOutFile = "D:/AUS/Aspect Huntley feed URLs/Automation Save Responses/ahresearch.xml" ...

  2. SFTP 安装与配置

    SFTP 安装与配置 sftp 是 Secure File Transfer Protocol 的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法.SFTP 为 SSH 的一部分,由于这种 ...

  3. firstpage 2015/5/21

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="firstPage.aspx ...

  4. 使用寄存器点亮LED等

    最基本的输入功能是检测外部输入电平,如把 GPIO引脚连接到按键,通过电平高低区分按键是否被按下. 基本结构分析 2. P-MOS管和 N-MOS管 main.c中的main函数

  5. 给tabhost加上点击监听,不是onTabChanged(String)监听

    给tabhost加上点击监听,不是onTabChanged(String)监听 2012-08-11 01:43 5209人阅读 评论(0) 收藏 举报 stringandroidlayoutnull ...

  6. sizeToFit & sizeThatFits

    [sizeToFit & sizeThatFits] 1.sizeToFit,根据sizeThatFits方法返回的大小来调整receiver的大小.自定义子类不应该覆盖这个方法. 2.siz ...

  7. 复杂HTML页面解析

    1.层叠样式表CSS可以让html元素呈现出差异化,网络爬虫可以通过class属性的值,轻松分出不同标签 findAll函数通过标签的名称和属性来查找标签 from urllib.request im ...

  8. 结对项目— 词频统计2(语言C++)

    结对对象:季天梦 博客地址:http://www.cnblogs.com/jitianmeng/ github链接:https://github.com/liuyutianlyt/EX_4.md 比例 ...

  9. TSQL--INT转换成指定长度字符串

    -- ================================================ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ...

  10. Centos 7 安装记录

    0.安装中选择最小安装 1.centos7安装图形界面 之前转载过一篇“centos6安装图形界面”的文章,地址见http://my.oschina.net/u/1169607/blog/335304 ...