2011-07-29 22 views
0

假设我有一个注册页面&注册确认页面。我输入用户 的详细信息到注册页面,导航到注册确认页面,其中 如果有任何错误,我可以返回到注册页面。JSF通过引用传递视图参数 - 必须实例化对象时

我打算使用视图参数将注册数据从注册页面提供到确认页面,反之亦然 。

假设有20个项目的数据,从页被移动到页面,这是 很多视图参数和大量setPropertyActionListeners的,尤其是 ,因为所有的数据被最终将会很好地封装在一个用户对象。

所以我想要做的就是将注册页面上的数据输入到用户记录的 属性中,并将其引用到寄存器 确认页面。什么给了我一个想法是看到BalusC WeakHashMap 转换器。这是一个JSF转换器,它有一个静态的弱哈希映射,并且 生成一个uuid作为映射条目的值,而对象引用作为 的关键。因此,通过将此指定为f:viewParam的转换器,您可以在查询字符串中发送 uuid。

这工作正常。我遇到的问题是,在注册页面上,我必须 用new获得一个User类的实例。然后,我可以这样做:

<h:inputText value="#{bean.user.firstname}"/> 

(等),并通过用户实例作为视图参数。它从 注册到确认页面正常工作。问题是,当我执行 ,从这个 确认页面发送用户参考返回注册页面我绝对不能阻止注册页面支持Bean 从重新实例后,二传一直是用户对象,作为查看参数的结果称为 。

所以转换器完成它的工作并从 哈希映射中检索User对象,在后台bean中调用setUser(),然后我看到用于User类激发的构造函数 。

我已经打过电话新用户()从bean的构造,在@PostConstruct, 在preRenderView(也检查,如果一个Ajax请求),但没有我尝试 防止视图参数的工作从惨遭洗盘如果新增,则涉及 。我确信有一个简单的解决方案,但我现在看不到 。

我很感激任何有关如何解决此问题的建议。

回答

1

经过多次尝试超过一年才找到一个坚实的长长期解决方案 终于到了这个问题!我找到了一个。该解决方案采用Apache Myfaces CDI扩展项目 的形式,也称为Myfaces CODI

这提供了额外的作用域,例如@ViewAccessScoped,它确保 如果bean被页面引用,那么它可用于该页面。还提供 支持会话组。在我想要 将对象引用从注册页面传递到注册确认页面的场景中, 确认页面可以直接在下一个请求上访问registerView bean。 或者,您可以@将一个bean注入另一个并在下一个 请求中访问它,或者使用源页面中的f:setPropertyActionListener。

Myfaces CODI可以很好地与Mojarra配合使用,也可以与诸如primefaces之类的jaxified组件库 一起使用。这个概念与Jboss Seam提供的相似, 虽然我发现额外的范围支持得到了更好的思考,并且我已经在glassfish 3.1.1上对 进行了测试,没有任何问题。

如果您使用@ManagedBean和范围注释从javax.faces.bean 包在你的代码,CODI截获这些注释,并使用它自己的 根据CDI版本,这样你就可以转换成CDI只需添加CODI作为 依赖于您的项目,并且不会更改任何代码。

对我来说,这就像是从黑白电视转向彩电,我希望 能早点发现这个东西。

CODI documentation

3

我遇到的问题是,在注册页面我必须得到一个用户类与新的实例。

那么最初创建这个新用户实例的代码是什么呢?如果你在preRenderView处理程序中这样做,那么你可以简单地检查null,不是吗?

如果视图参数和转换器没有完成他们的工作,user仍然是空的,你创建一个新的实例。这个bean的构造函数和@PostConstruct在这里不会有什么好处,因为它们都在view参数做它的事情之前运行,但保证在它后面运行preRenderView事件。

@ManagedBean 
public class Bean { 

    private User user; 

    public void onPreRenderView() { 
     if (user == null) { 
      user = new User(); 
     } 
    } 
} 

(有什么要另外考虑的是,conversation scope已经这样做你想在这里做什么。这是CDI不是JSF的一部分,但如果你是在Java EE 6 Web Profile的运行(JBoss AS 6或7,Glassfish V3,Resin 4,...)你已经拥有它,否则它只是一个额外的瓶子。)

+0

嗨阿尔詹,我试过这个,但唉,它没有奏效。最近我花了几天的时间尝试使用glassfish 3.1进行焊接,但问题太多,即使使用焊缝1.1.1。我对CDI的一个大问题是缺乏视图范围,我想要走的路是缝3 @RenderScoped或Steven Verborgh自定义视图范围。我现在几乎已经认识到这个问题了,但现在是凌晨3点,我明天最好结束。感谢您的回复。 – Oversteer

+0

关于'@ ViewScoped'缺少CDI,是的这是一个大问题。但是Seam3又添加了它。与Seam2不同,Seam3由许多小型可移植扩展组成,因此您只需将该部分添加到应用程序即可修复此问题,而不是添加所有内容。或者,如果您只需要对话范围,那么只有1个bean可以是CDI对话范围,其他bean可以保留JSF ManagedBeans(但这可能并不那么漂亮)。 –

+0

问题在于seam3与glassfish 3.0.1/3.1(http:// seamframework)有很多兼容性问题。org/Seam3/Compatibility)我花了好几天的时间试图让Verborgh视图范围与CDI一起工作,还有Seam 3 @RenderScoped,并且都不能用于glassfish。在谈话范围内,我真的不知道什么时候结束对话,以及如何处理浏览器后退按钮?我只是要使用会话地图。我最初的问题是,在视图之间weakhashmap中的数据是垃圾收集和jsf不会调用setter。感谢您的意见。 – Oversteer