request.getSession(true/false)的区别
【原文链接】: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)的区别的更多相关文章
- 【转】于request.getSession(true/false/null)的区别
http://blog.csdn.net/gaolinwu/article/details/7285783 关于request.getSession(true/false/null)的区别 一.需求原 ...
- 关于request.getsession(true|false)
request.getSession(true):若存在会话则返回该会话,否则新建一个会话.request.getSession(false):若存在会话则返回该会话,否则返回NULL
- 转:request.getSession(true)和request.getSession(false)的区别
1.转自:http://wenda.so.com/q/1366414933061950?src=150 概括: request.getSession(true):若存在会话则返回该会话,否则新建一个会 ...
- request.getSession(true)和request.getSession(false)的区别
request.getSession(true)和request.getSession(false)的区别 request.getSession(true):若存在会话则返回该会话,否则新建一个会 ...
- 如何获得 request, "request.getSession(true).setAttribute("a",a);"与“request.setAttribute("a",a);”区别
protected ServletContext getServletContext() { return ServletActionContext.getServletContext();} pro ...
- request.getSession()、reqeust.getSession(false)和request.getSession(true)
getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象 getSession(false):当session存在 ...
- 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)--转
出处:http://blog.csdn.net/xxd851116/archive/2009/06/25/4296866.aspx [前面的话] 在网上经常看到有人对request.getSessio ...
- 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)
本文属于本人原创,转载请注明出处:http://blog.csdn.net/xxd851116/archive/2009/06/25/4296866.aspx [前面的话] 在网上经常看到有人对req ...
- request.getSession()几种获取情况之间的差异
一.三种情况如下 HttpSession session = request.getSession(); HttpSession session = request.getSession(true); ...
随机推荐
- [SoapUI]怎样保存response到本地文件夹
def myOutFile = "D:/AUS/Aspect Huntley feed URLs/Automation Save Responses/ahresearch.xml" ...
- SFTP 安装与配置
SFTP 安装与配置 sftp 是 Secure File Transfer Protocol 的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法.SFTP 为 SSH 的一部分,由于这种 ...
- firstpage 2015/5/21
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="firstPage.aspx ...
- 使用寄存器点亮LED等
最基本的输入功能是检测外部输入电平,如把 GPIO引脚连接到按键,通过电平高低区分按键是否被按下. 基本结构分析 2. P-MOS管和 N-MOS管 main.c中的main函数
- 给tabhost加上点击监听,不是onTabChanged(String)监听
给tabhost加上点击监听,不是onTabChanged(String)监听 2012-08-11 01:43 5209人阅读 评论(0) 收藏 举报 stringandroidlayoutnull ...
- sizeToFit & sizeThatFits
[sizeToFit & sizeThatFits] 1.sizeToFit,根据sizeThatFits方法返回的大小来调整receiver的大小.自定义子类不应该覆盖这个方法. 2.siz ...
- 复杂HTML页面解析
1.层叠样式表CSS可以让html元素呈现出差异化,网络爬虫可以通过class属性的值,轻松分出不同标签 findAll函数通过标签的名称和属性来查找标签 from urllib.request im ...
- 结对项目— 词频统计2(语言C++)
结对对象:季天梦 博客地址:http://www.cnblogs.com/jitianmeng/ github链接:https://github.com/liuyutianlyt/EX_4.md 比例 ...
- TSQL--INT转换成指定长度字符串
-- ================================================ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ...
- Centos 7 安装记录
0.安装中选择最小安装 1.centos7安装图形界面 之前转载过一篇“centos6安装图形界面”的文章,地址见http://my.oschina.net/u/1169607/blog/335304 ...