`
yanhua
  • 浏览: 87824 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

讨论:如何处理SessionScope和序列化自己的关系?

阅读更多

事情的起因是这样的:我想使用JSF2.0的ViewScope的MangedBean作为一个编辑界面的backing bean,但是发现它竟然要求这个bean必须要求支持序列化——因为ViewScope是通过把状态保存在ViewRoot上来实现的,这又依赖于StateManager,它在保存状态时需要序列化。本来让这个bean实现序列化接口就可以了,不过我这个bean可能还有一个属性是一个Spring的bean,难道我让这个Spring的bean也要支持序列化吗?

 

是的,问题的关键是序列化保存状态的问题引起的,其实SessionScope也会有这个问题——如果需要支持Session的复制的话。看来这不是JSF特有的问题,Spring中应该也有相似的问题,果不其然,我在Spring的论坛里找到了一个帖子:

 

http://forum.springsource.org/showthread.php?t=56569

 

写道
Hi,

we have a relatively large Spring-based web application. Our beans are generally of two types: application-wide services (stateless, usually singleton-scoped beans) and user-specific beans (typically stateful, session-scoped beans). Session-scoped beans are often injected with application beans and other session-scoped beans.

The problem we are facing now is that in this constellation, the HTTP session is not serializable since session beans reference application beans, which are not serializable. Another problem is that even if referenced bean is serializable, then after deserialization we'll get an multiple instances (unless we implement readResolve() and stuff).

So I'm really puzzled about how to make the HTTP session serializable in the case described above. My ideas are below:

1. Wrap all of the beans in a serializable scoped proxies. If target object is not serializable, scoped proxy will just serialize null and retrieve a new instance when called after deserialization.

This may work. However, it seems to be an overkill for me since it seems as ALL of the beans must be proxied. Means every method call will go through a proxy which I don't like much.

2. Invent some kind of a mechanism which would reinject transient properties. That is, serializable beans which reference non-serializable beans mark corresponding fields as transient. These values are not serialized. Then, when session is deserialized and the application accesses a deserialized session bean, transient properties (present in the bean definition in Spring) are re-injected by the bean factory.

From the Spring user perspective this would be the most convenient thing: just mark field as transient and Spring ("extended" session scope or whatever) will reinject the transient properties into the deserialized instance. However, I'm not sure if this is a correct approach. I also don't know what to do with bean initialization (like InitializingBean and so on). I'm also not sure if this is valid at all and if it is technically possible.

So I'd be very grateful if you guys comment on my problem/ideas.
 

如果你在Spring的SessionScope的bean中引用SingletonScoped的bean的话也会存在同样的问题。上面的帖子给出两种可能的解决方案,不过并不完美。或许本不该这么用?避免这么使用吗?

 

回到JSF,有时候这么用有很方便,我想出两种解决方案:

 

  • 在JSF的SessionScope和ViewScope的managed bean中不注入Spring的bean,这两种Scope的managed bean只保存一般的属性和领域对象。处理界面的操作的部分放入另一个RequestScope的managed bean中,并在这个RequestScope的managedbean中引用SessionScope或ViewScope的managed bean。缺点就是无端多出几个manged bean来。
  • 不使用IoC的方式注入Spring的bean到managed bean中,而是每次通过Spring的Application Context去getBean,这样manged bean中不存在对Spring bean的引用,序列化就不成问题了。缺点就是可能牺牲一些代码的优雅性,Mock测试mangaged bean的时候也不太方便。不过一般很少mock测试manged bean。

还有更好的解决方案吗?

 

最近开到Gavin King发表的一个评论上说使用JSF2.0,EJB和CDI的时候不需要考虑这个序列化的问题,也许JSF和EJB,CDI结合的更完美些,毕竟都是JEE的标准。

 

分享到:
评论
1 楼 yanhua 2010-07-17  
ViewScope出现不能序列化的问题是因为:
<context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
设成server就没问题了,不过如果集群环境下session复制是不是还有问题?

相关推荐

    domino xapges 开发sessionScope

    domino xapges 开发sessionScope

    El-表达式简介

    EL表达式 1、EL简介 1)语法结构 ${expression} 2)[]与.... EL 提供.和[]两种运算符来存取数据。... 当要存取的属性名称中包含一些特殊字符,如.... ${sessionScope.user[data]}中data 是一个变量

    EL表达式(详解)

    EL表达式 1、EL简介 1)语法结构 ${expression} 2)[]与.... EL 提供.和[]两种运算符来存取数据。 当要存取的属性名称中包含一些特殊字符,如.... ${sessionScope.user[data]}中data 是一个变量 3)变量

    JSTL操作支持多国语言

    JSTL操作支持多国语言,提供参考. test:${fn:length(sessionScope.basePath3)}

    EL表达式的详细使用

    对于单引号、双引号和反斜杠,使用反斜杠字符作为转义序列。必须注意,如果在字符串两端使用双引号,则单引号不需要转义。 Null null 2、操作符 JSP 表达式语言提供以下操作符,其中大部分是 Java 中常用的操作...

    domino xpags开发 控件 富文本域获取和保存

    Domino XPAGS 开发控件富文本域获取和保存 Domino XPAGS 是一种基于 Lotus Domino 的开发平台,用于构建企业级应用程序。本文将详细介绍 Domino XPAGS 开发控件富文本域获取和保存的相关知识点。 一、富文本域获取...

    EL表达式 (详解)

    它们基本上就和JSP的pageContext、request、session和application一样; 在EL中,这四个隐含对象只能用来取得范围属性值,即getAttribute(String name),却不能取得 其他相关信息。 例如:我们要取得session中...

    ADF进页面前默认赋值(Groovy表达式)

    NULL 博文链接:https://563432906.iteye.com/blog/2288859

    简单的一个学生管理系统 servlet+JSP

    &lt;c:when test="${sessionScope.currentPage==sessionScope.countPage}"&gt; 下一页 &lt;/c:when&gt; &lt;c:otherwise&gt; ${nextPage}"&gt;下一页 &lt;/c:otherwise&gt; &lt;/c:choose&gt; &lt;c:...

    Debug测试使用需要修改

    Debug测试使用需要修改 Debug测试使用需要修改 Debug测试使用需要修改

    简单的租房发布系统--zf4(租房4)

    这是一个关于租房信息发布的信息系统&lt;c:forEach items="${list}" var="fwxx"&gt; ...&lt;logic:equal name="fwxx" property="uid" value="${sessionScope.user.uid}"&gt; [编辑] [删除] &lt;/logic:equal&gt; ... &lt;/c:forEach&gt;

    EL表达式详细介绍

    和[]两种运算符来存取数据。  当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用 []。例如:  ${user.My-Name}应当改为${user["My-Name"] }  如果要动态取值时,就可以用[]来做...

    EL与JSP相关内置对象

    EL内置对象: pageContext pageScope requestScope sessionScope applicationScope param paramValues header headerValues cookie initParam

    SpringWebFlow学习笔记:全XML配置方式,纯流程跳转,不带有功能实现

    本文是一篇初学Spring Web Flow的Demo,xml配置,纯流程跳转。

    JSP中EL表达式的用法详解(必看篇)

    ${sessionScope.user.sex} 所有EL都是以${为起始、以}为结尾的。上述EL范例的意思是:从Session的范围中,取得 用户的性别。假若依照之前JSP Scriptlet的写法如下: User user =(User)session.getAttribute(“user”...

    EL表达式详解

    1) EL概述 ·EL表达式用${ }表示,可用在所有的 HTML和 JSP 标签中,作用是代替 JSP 页面中复杂 的 JAVA代码. ·EL表达式可操作常量、...sessionScope 表示会话范围内的变量. applicationScope 表示应用范围的变量.

    浅谈SpringMVC jsp前台获取参数的方式 EL表达式

    ${sessionScope.msg2} JAVA: ModelAndView ModelMap Model里添加的参数 JSP: 直接用${参数名} JAVA: 前台表单里的信息,或者是直接在url后面以?name=value&name2=value2形式传到后台的 JSP: ${param.参数名} ...

    网上书城bookstore

    apache.commons.dbutils 翻页 购物车 sessionScope

    jsp中关于EL表达式的应用

    1.pageScope:所有页面作用域变量的集合(java.util.Map) 2.requestSCope:... 3.sessionScope:所有会话作用域变量的集合(java.util.Map) 4.applicationScope:所有应用作用域变量的集合(java.util.Map)

    在js文件中写el表达式取不到值的原因及解决方法

    今天在js文件中,写el表达式取不到值(代码如下),百度一翻,现总结如下: 1、javascript是客户端执行,EL是在服务端执行,而服务端比客户端先执行,所以取不到值 2、要想获取”${isLogin}”的值,可以在jsp中,用一个...

Global site tag (gtag.js) - Google Analytics