【原文链接】: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)。

  1. @Override
  2. public HttpSession getSession(boolean create) {
  3. if (request == null) {
  4. throw new IllegalStateException(
  5. sm.getString("requestFacade.nullRequest"));
  6. }
  7. if (SecurityUtil.isPackageProtectionEnabled()){
  8. return AccessController.
  9. doPrivileged(new GetSessionPrivilegedAction(create));
  10. } else {
  11. return request.getSession(create);
  12. }
  13. }
  14. @Override
  15. public HttpSession getSession() {
  16. if (request == null) {
  17. throw new IllegalStateException(
  18. sm.getString("requestFacade.nullRequest"));
  19. }
  20. // 直接调用getSession(true)
  21. return getSession(true);
  22. }

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

  1. /**
  2. * @return the session associated with this Request, creating one
  3. * if necessary and requested.
  4. *
  5. * @param create Create a new session if one does not exist
  6. */
  7. @Override
  8. public HttpSession getSession(boolean create) {
  9. Session session = doGetSession(create);
  10. if (session == null) {
  11. return null;
  12. }
  13. return session.getSession();
  14. }

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

  1. protected Session doGetSession(boolean create) {
  2. // There cannot be a session if no context has been assigned yet
  3. Context context = getContext();
  4. if (context == null) {
  5. return (null);
  6. }
  7. // Return the current session if it exists and is valid
  8. // 如果当前session存在且有效,返回当前session
  9. if ((session != null) && !session.isValid()) {
  10. session = null;
  11. }
  12. if (session != null) {
  13. return (session);
  14. }
  15. // Return the requested session if it exists and is valid
  16. // 这里有读写锁控制并发
  17. Manager manager = context.getManager();
  18. if (manager == null) {
  19. return (null); // Sessions are not supported
  20. }
  21. if (requestedSessionId != null) {
  22. try {
  23. session = manager.findSession(requestedSessionId);
  24. } catch (IOException e) {
  25. session = null;
  26. }
  27. if ((session != null) && !session.isValid()) {
  28. session = null;
  29. }
  30. if (session != null) {
  31. session.access();
  32. return (session);
  33. }
  34. }
  35. // Create a new session if requested and the response is not committed
  36. // create为false时,返回null;create为true时创建一个新的session
  37. if (!create) {
  38. return (null);
  39. }
  40. if (response != null
  41. && context.getServletContext()
  42. .getEffectiveSessionTrackingModes()
  43. .contains(SessionTrackingMode.COOKIE)
  44. && response.getResponse().isCommitted()) {
  45. throw new IllegalStateException(
  46. sm.getString("coyoteRequest.sessionCreateCommitted"));
  47. }
  48. // Re-use session IDs provided by the client in very limited
  49. // circumstances.
  50. String sessionId = getRequestedSessionId();
  51. if (requestedSessionSSL) {
  52. // If the session ID has been obtained from the SSL handshake then
  53. // use it.
  54. } else if (("/".equals(context.getSessionCookiePath())
  55. && isRequestedSessionIdFromCookie())) {
  56. /* This is the common(ish) use case: using the same session ID with
  57. * multiple web applications on the same host. Typically this is
  58. * used by Portlet implementations. It only works if sessions are
  59. * tracked via cookies. The cookie must have a path of "/" else it
  60. * won't be provided for requests to all web applications.
  61. *
  62. * Any session ID provided by the client should be for a session
  63. * that already exists somewhere on the host. Check if the context
  64. * is configured for this to be confirmed.
  65. */
  66. if (context.getValidateClientProvidedNewSessionId()) {
  67. boolean found = false;
  68. for (Container container : getHost().findChildren()) {
  69. Manager m = ((Context) container).getManager();
  70. if (m != null) {
  71. try {
  72. if (m.findSession(sessionId) != null) {
  73. found = true;
  74. break;
  75. }
  76. } catch (IOException e) {
  77. // Ignore. Problems with this manager will be
  78. // handled elsewhere.
  79. }
  80. }
  81. }
  82. if (!found) {
  83. sessionId = null;
  84. }
  85. }
  86. } else {
  87. sessionId = null;
  88. }
  89. session = manager.createSession(sessionId);
  90. // Creating a new session cookie based on that session
  91. if (session != null
  92. && context.getServletContext()
  93. .getEffectiveSessionTrackingModes()
  94. .contains(SessionTrackingMode.COOKIE)) {
  95. Cookie cookie =
  96. ApplicationSessionCookieConfig.createSessionCookie(
  97. context, session.getIdInternal(), isSecure());
  98. response.addSessionCookieInternal(cookie);
  99. }
  100. if (session == null) {
  101. return null;
  102. }
  103. session.access();
  104. return session;
  105. }

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

  1. @Override
  2. public Manager getManager() {
  3. Lock readLock = managerLock.readLock();
  4. readLock.lock();
  5. try {
  6. return manager;
  7. } finally {
  8. readLock.unlock();
  9. }
  10. }
  11. @Override
  12. public void setManager(Manager manager) {
  13. Lock writeLock = managerLock.writeLock();
  14. writeLock.lock();
  15. Manager oldManager = null;
  16. try {
  17. // Change components if necessary
  18. oldManager = this.manager;
  19. if (oldManager == manager)
  20. return;
  21. this.manager = manager;
  22. // Stop the old component if necessary
  23. if (oldManager instanceof Lifecycle) {
  24. try {
  25. ((Lifecycle) oldManager).stop();
  26. ((Lifecycle) oldManager).destroy();
  27. } catch (LifecycleException e) {
  28. log.error("StandardContext.setManager: stop-destroy: ", e);
  29. }
  30. }
  31. // Start the new component if necessary
  32. if (manager != null) {
  33. manager.setContext(this);
  34. }
  35. if (getState().isAvailable() && manager instanceof Lifecycle) {
  36. try {
  37. ((Lifecycle) manager).start();
  38. } catch (LifecycleException e) {
  39. log.error("StandardContext.setManager: start: ", e);
  40. }
  41. }
  42. } finally {
  43. writeLock.unlock();
  44. }
  45. // Report this property change to interested listeners
  46. support.firePropertyChange("manager", oldManager, manager);
  47. }

结论:

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. MySQL redo log及recover过程浅析

    写在前面:作者水平有限,欢迎不吝赐教,一切以最新源码为准. InnoDB redo log 首先介绍下Innodb redo log是什么,为什么需要记录redo log,以及redo log的作用都 ...

  2. Dom4j入门

    一.Dom4j API生成xml文件 @Test public void bulidXmlByDom4j(){ //创建document对象 Document document = DocumentH ...

  3. JavaScript 对象属性作实参以及实参对象的callee属性

    参考自<<JavaScript权威指南 第6版>> /* * 将对象属性用作实参, 从而不必记住参数的顺序. */ function arraycopy(from,from_s ...

  4. dns记录类型(转)

    NS:(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串.通过主机名,最终 ...

  5. RocketMQ 服务器3模式

    22 a b-s---------------------------sh mqbroker -c $ROCKETMQ_HOME/conf/2m-2s-async/broker-a.propertie ...

  6. Spring+shiro配置JSP权限标签+角色标签+缓存

    Spring+shiro,让shiro管理所有权限,特别是实现jsp页面中的权限点标签,每次打开页面需要读取数据库看权限,这样的方式对数据库压力太大,使用缓存就能极大减少数据库访问量. 下面记录下sh ...

  7. bootstrap-treeview中文API 以及后台JSON数据处理

    bootstrap-treeview   简要教程 bootstrap-treeview是一款效果非常酷的基于bootstrap的jQuery多级列表树插件.该jQuery插件基于Twitter Bo ...

  8. Cesium Language (CZML) 入门2 — CZML Content(CZML的内容)

    原文:https://github.com/AnalyticalGraphicsInc/cesium/wiki/CZML-Content 以下是描述CZML文档或者流中可能存在的内容.要解释CZML文 ...

  9. 毕业回馈—89C51之GPIO使用

    STC89C51系列单片机共有如下几类GPIO口: (1)P0.0-P0.7: 对应DIP40封装的39-32号引脚:P0口既可以作为输入/输出GPIO口,也可以作为地址/数据复用总线使用. a)P0 ...

  10. QT的配置及目录结构

    作者:一去丶二三里 来源:CSDN 原文:https://blog.csdn.net/liang19890820/article/details/51774724 注意:所有的配置中,/user中的/ ...