一,问题描述
用户会话session是servet规范中标准的对象,它代表了用户活动的生命周期,因此在我们以往的web开发中,经常将用户信息放置到session对象中。然而随着真正意义上的portal时代的到来,portlet的开发让身在其中的人们感到了稍许的不自在,其中很重要的一个因素就是对于session的管理。

在portal中,一个war是一系列portlet的组合,它的意义等价于以前servlet开发中的webapp,因此一个portlets的war就代表了部署在portal server上的一个应用程序,我们又知道在servlet规范中,session的范围是和用户会话相关的,而此会话是相对于具体的某个应用的,即同一个用户登录到不同的web应用后,他的session也是不同的,例如某个用户登录了部署在同一个服务器上的两个web应用:办公自动化系统和财务系统,那么在办公自动化系统中会有该用户的一个sesion,而在财务系统中会有用户的另外一个不同的session。

在portal server中也是这样的,既然不同的portlets war代表不同的应用,那么不同的portlets war之间session也是不同的,即是不能共享的。我想这是我们所能接受的,但是在同一个portlets war中的portlet之间共享session,这应该是个可以达到的基本要求吧,但是对于这一点,不同的portlet规范给出的答案也是不一样的。

下面我们看一下JSR168和IBM Portlet对session问题的回答。

二,不同portlet规范对session问题的回答

1,JSR168方面

JSR168是JCP关于portlet的一个标准,它在自己框架中加入了对session问题的解决方法,在JSR168中,portlet session是可以设置作用范围的,目前有两个作用范围:应用范围(application_scope)和portlet范围(portlet_scope),对于应用范围的session属性,是在同一个portlets war中共享的,而对于portlet范围的session属性,只能是在该portlet具体实例内共享的。如下是JSR168规范中的API:

PortletSession session = request.getPortletSession();

session.setAttribute("attributeName1", "attributeValue1", PortletSession.APPLICATION_SCOPE);
session.setAttribute("attributeName2", "attributeValue2", PortletSession.PORTLET_SCOPE);
session.setAttribute("attributeName3", "attributeValue3");

如上,设置了session属性的范围后,attributeName1是可以在整个portlets war内取到的,而attributeName2只能在该portlet 实例内取到,attributeName3没有设置作用范围,则默认位portlet_scope,因为也只能在该portlet实例内取到。

2,IBM Portlet方面

可以说IBM portlet在同一个portlets war内session的共享做的很不够,在wps4.1中可以通过如下方面解决:在web.xml的servlet定义中,加入下面的参数:

< init-param>
    < param-name> com.ibm.wps.portlet.session< /param-name>
    < param-value> shared< /param-value>
< /init-param>

但是这种共享并不是想象中的在portlets war内共享,而是只有部署在同一个页面中的该war中的portlet实例之间才能共享session,也就是说,即使是同一个portlets war的portlets,如果被部署在不同的页面,那么他们之间的session也是不能共享的,这显然限制很大,没有太大的实际上的意义。

三,实际的portlet项目开发中,该如何解决session的问题

通过前面已经知道,如果使用JSR168开发,则问题基本上可以解决,具体请参看上面的叙述,但是如果使用IBM portlet开发,则需要使用其它方式了。下面介绍的是针对IBM portlet在session方面所做的一种方式,效果还是可以的。

通过查阅相关资料以及进行相关实验,我们最终发现,IBM portlet session基本上只能在具体的 concrete portlet实例(即已经部署到页面中的某个portlet实例)范围内有效,因此我们每个portlet都需要重新组建session,即通过用户标识以及其它一些辅助类,获取用户相关信息并将信息设置到portlet session之中,为了能让每个portlet在做就体逻辑之前就将session信息初始化好,我采用如下的一个方案:

通过IBM portlet规范知道,每个concrete portlet可以定义他的视图默认页面,我们一般定义为某个路径下的index.jsp,因为到index.jsp的时候,portlet的其它逻辑还没有执行,因此此时是获取用户相关数据并存放到portlet session中的好时机,如下:

<%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<portletAPI:init/>
<%
//获取相关数据放置到session属性中。
com.ibm.portal.puma.User portalUser= (com.ibm.portal.puma.User) portletRequest.getUser();
String userId=portalUser.getUserID();
session.setAttribute("userId",userId);
String department=new UserManager().getUserDepartmentBySn(userId);
session.setAttribute("department",department);
//准备完session信息后,导向到具体的应用逻辑页面。
portletConfig.getContext().include("next.jsp",portletRequest,portletResponse);
%>
按照上面的方式,原来需要在HttpSession存储的信息,现在每个需要这些信息的portlet都自己去后台取一次,然后设置到自己的PortletSession之中。这种方式虽然感觉笨了一些,但至少是一种解决方式,可以尝试一下,还是不错的。

四,从portlet session问题看portal

portlet session的问题可能是不少人所不能理解的,为什么用户登录portal后,他所看到的东西可能不是在同一个session范围内,为什么同一个用户看到的不同的portlet可能会属于不同的session。其实这涉及到对portal的理解问题。

portal我们知道是门户的意思,也知道上面是一个个的portlet应用,每个portlet可能代表着一个不同的应用,这里的应用和上面说的应用可能概念还不太一样,这里的应用主要是指业务。

另外我们知道portlet有自己的规范,只要按照规范开发出的portlet,则就可以部署到portal server之中,那么在portal server中,很有可能包含了各种各样的portlet,有些portlet是同一个业务的,而另外一些portlet是为另一个业务的,请注意一点,portal server中的这些业务,并不一定只包含你自己做的,或你们公司自己做的,也有可能包含各个厂商自己已经做好的,还有可能客户后来又新添加的。

这样一来,如果不同业务或风马牛不相及的业务之间可以共享session的话,那么很可能会引起session的混乱,例如厂家A的portlet在session中设置了company属性为company_A,而厂家B的portlet在session中设置了company属性为company_B,如果session是在用户登录后的所有portlet之间共享的话,那么就会引起数据混乱,而导致严重的业务问题。

基于此,portal server中提出了portlets应用的概念(portlet war),一个portlets 应用就是一组portlets,这些portlets被打成一个符合portal要求的war包,然后可以部署到portal server之中。在portal server中,portal会将每个portlet应用看作是一个独立的应用,就好像是Tomcat下的webapps中的应用一样,也许你觉得将portlets 应用看作是web应用很难,但你想一想,一个portlets应用中,包含了一个web应用所有的东西,有独立的web.xml,有独立的lib和classes以及tld等等,只能说portlet应用不仅是一个web应用,而且是一个实现了portlet功能的更为强大的web应用。

我们知道一个portal server中可以部署多个这样的portlet 应用,这实际上就相当于在一个portal server中部署了多个web应用,再想下去你可能会觉得非常惊叹:既然不同的portlet war是不同的web应用(就像tomcat webapps下的应用一样),那么我们登录portal后,实际上看到的是多个web应用的聚合,不知你是否理解我现在说的,你想想以前访问tomcat时,我们一般都是通过某个context path然后访问到webapps下的具体应用,但是你是否想过如果将webapps下的所有应用在一个系统在内聚合访问,那将是怎样的一番景象呢!portal做的就是这个!

因此portets 应用(portlets war)之间不能共享session是理所当然的,就好像tomcat webapps下的不同应用不能共享session是一个道理,当然同一个portlets应用内(即同一个web应用内)共享session这应该是被支持的,JSR168做的就很好,IBM的portlet在这方面真是有些问题。

基于此我们再理解一下Websphere中的server1和WebSphere_Portal两个服务器,我们以前可能会奇怪,为什么我们可以直接在server1部署web应用程序,然后通过url进行访问,而WebSphere_Portal中却不可以部署web应用程序然后通过url访问呢,现在可以告诉你,server1部署的web应用是符合servlet标准的web应用,或者说是普通的web应用,而再WebSphere_Portal中实际上也可以部署web应用,只是只能部署较为特殊的一种web应用,即portlets应用。另外我们在Websphere控制台中只能部署企业级应用程序(包括普通的web应用),我们在里面找不到可以部署portlet这种特殊web应用的地方,实际上我们都清楚,portlet应用的部署是在portal的管理短实现的,而不是在websphere的控制台中.

portlet session共享相关推荐

  1. 解决nginx负载均衡的session共享问题

    之前有写过ubuntu环境下搭建nginx环境,今天来谈一下nginx session共享问题,查了一些资料,看了一些别人写的文档,总结如下,实现nginx session的共享服务器有多台,用ngi ...

  2. nginx+tomcat+memcache实现负载均衡、session共享

    实验架构图: Table of Contents 1.配置tomcat 2.安装memcache 3.查看tomcat和memcache是否配置好 4.nginx实现负载均衡: 5.客户端进行测试: ...

  3. Spring Boot(十一)Redis集成从Docker安装到分布式Session共享

    2019独角兽企业重金招聘Python工程师标准>>> 一.简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并 ...

  4. 再谈session共享

    之前一篇已经写过了<springboot中redis的使用和分布式session共享问题>,但是示例不完全,本文加以完善. 使用spring-session-data-redis解决ses ...

  5. Redis解决websocket在分布式场景下session共享问题

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/weixin_45089791/article/ details/118028312 在显示项目中 ...

  6. Redis + Tomcat + Nginx 集群实现 Session 共享

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 蕃薯耀 链接 | www.cnblogs.com/fan ...

  7. php java session共享_php 函数session_id()思考。实现同服务器下session共享

    session_id() session_id() 存取目前 session 代号. 语法: string session_id(string [id]); 本函数可取得或者重新配置目前存放 Sess ...

  8. 分布式架构下,Session 共享有什么方案?

    来自:会点代码的大叔 分布式架构下的 Session 共享,也称作分布式 Session 一致性:分布式架构下 Session 共享有哪些问题,又有哪些解决方案,让我们一起看一下. 01 Sessio ...

  9. 分布式系统,session共享方案

    服务器(tomcat)之间进行session同步 服务器之间进行Session同步,这样可以保证每个服务器上都有全部的Session信息,不过当服务容器数量比较多的时候,同步是会有延迟甚至同步失败: ...

最新文章

  1. 中国女博士的「水淹食堂」大法:单目视频完美重建3D场景,画面毫无违和感...
  2. 【254天】跃迁之路——程序员高效学习方法论探索系列(实验阶段12-2017.10.17)...
  3. 值得收藏的 14 个 Linux 下 CPU 监控工具
  4. 企鹅帝国的疯狂反扑!
  5. 深度学习-Tensorflow2.2-卷积神经网络{3}-卷积神经网络CNN基础-11
  6. android IntentService
  7. hadoop SecondNamenode
  8. c语言转图形化,「分享」C语言如何编写图形界面
  9. android callmanager.java,如何使用Mobile-SDK-Android正确注销DJISDKManager和SDKManagerCallback应用程序?...
  10. 区块链共识问题都有什么?
  11. uploadify 上传文件出现HTTP 404错误
  12. 【数据集】BDD、KITTI、Cityscapes和Foggy Cityscapes百度云链接
  13. (四)DIH导入结构化数据
  14. java 切割冒号_java split 冒号(java中split是什么意思啊)
  15. 代码坏味道 之 21 被拒绝的遗赠 refused bequest
  16. 黑客们很喜欢骇客交锋,虽然本片不被影评人认可
  17. Cannot assign requested address问题总结
  18. 第三方测试什么意思?国内知名第三方测试公司排名
  19. word中删除页眉的横线
  20. 【解决方案】医院医疗安防视频监控系统搭建及集成统一管理方案介绍

热门文章

  1. android5.0联系人铃声设置和来电读取分析
  2. Mybatis的#{}与${}占位符
  3. 《Java并发编程:设计原则与模式 第二版》pdf 附下载链接
  4. VRML语法基础和简介
  5. ObjectARX简介
  6. 链表基础知识详解(非常详细简单易懂)
  7. maven 更改版本号
  8. MySQL之orderby详解
  9. python traceback_python出错时traceback的解读
  10. 今天下载了一个人分享的pdf书籍,但是是加密压缩,想要人买密钥,下载前又没有说明,很无奈