JSF支持bean结构(最佳实践)

Zac*_*ese 116 java jsf

我希望在这篇文章中,我可以得到人们对JSF页面和支持bean之间接口的最佳实践的看法.

我永远无法解决的一件事是我的支持豆的结构.此外,我从未找到关于这个主题的好文章.

什么属性属于哪个支持bean?何时适合向给定bean添加更多属性,而不是创建新bean并将属性添加到其中?对于简单的应用程序,考虑到将一个bean注入另一个bean所涉及的复杂性,为整个页面只有一个支持bean是否有意义?支持bean是否应该包含任何实际的业务逻辑,还是应该严格包含数据?

随意回答这些问题以及可能出现的任何其他问题.


至于减少JSF页面和支持bean之间的耦合,我从不允许JSF页面访问任何支持bean属性的属性.例如,我从不允许以下内容:

<h:outputText value="#{myBean.anObject.anObjectProperty}" />
Run Code Online (Sandbox Code Playgroud)

我总是需要这样的东西:

<h:outputText value="#{myBean.theObjectProperty}" />
Run Code Online (Sandbox Code Playgroud)

支持bean值为:

public String getTheObjectProperty()
{
    return anObject.getAnObjectProperty();
}
Run Code Online (Sandbox Code Playgroud)

当我循环遍历集合时,我使用包装类来避免向下钻取到数据表中的对象.

一般来说,这种方法对我来说是"正确的".它避免了视图和数据之间的任何耦合.如果我错了,请纠正我.

小智 144

您可能想要检查一下:区分不同类型的JSF托管bean.

以下是Neil Griffin在上文中定义的不同bean类型的描述:

  • Model Managed-Bean:通常是会话范围. 这种类型的托管bean参与了MVC设计模式的"模型"关注.当你看到"模型"这个词时 - 想想数据.JSF模型bean应该是遵循JavaBean设计模式的POJO,其中getter/setter封装属性.模型bean的最常见用例是数据库实体,或者只是表示数据库查询结果集中的一组行.
  • 支持托管Bean:通常请求范围.这种类型的托管bean参与MVC设计模式的"视图"关注.backing-bean的目的是支持UI逻辑,并且与Facef组合中的JSF视图或JSF表单具有1 :: 1的关系.虽然它通常具有带有关联getter/setter的JavaBean样式属性,但它们是View的属性 - 而不是底层应用程序数据模型的属性.JSF支持bean也可能有JSF actionListener和valueChangeListener方法.
  • Controller Managed-Bean:通常请求范围. 这种类型的托管bean参与MVC设计模式的"控制器"关注.控制器bean的目的是执行某种业务逻辑并将导航结果返回给JSF导航处理程序.JSF控制器bean通常具有JSF操作方法(而不是actionListener方法).
  • 支持Managed-Bean:通常是会话或应用程序范围. 这种类型的bean"支持"MVC设计模式的"视图"关注中的一个或多个视图.典型的用例是向JSF h:selectOneMenu下拉列表提供ArrayList,这些列表出现在多个JSF视图中.如果下拉列表中的数据特定于用户,则bean将保留在会话范围内.但是,如果数据适用于所有用户(例如省份的下拉列表),则bean将保留在应用程序范围内,以便可以为所有用户缓存该数据.
  • Utility Managed-Bean: 通常是应用程序范围. 这种类型的bean为一个或多个JSF视图提供了某种类型的"实用程序"功能.一个很好的例子可能是FileUpload bean,它可以在多个Web应用程序中重用.

  • 由于http://stackoverflow.com/a/7223910中提到的原因,我对其进行了投票 (24认同)
  • 尽管如此,我仍然无法确定这个答案目前是71个赞成票.谁实现了根据这些规则的JSF应用程序必须无疑事后对JSF咆哮是一个非常不透明的框架,他们的JSF应用程序是一个大码的混乱,他们都指责JSF本身,而不是自己的不良做法基于错误的教训,所谓学习了"最佳实践". (10认同)
  • 这是一篇很棒的文章.我以前从未见过它,我很高兴你发布它.投票决定投票的人是疯了.这不是特定于iceFaces的. (8认同)
  • 实际文章的链接似乎消失了. (2认同)

All*_*sen 14

好问题.当我搬到JSF时,我遇到了同样的困境.这真的取决于你的应用程序.我来自Java EE世界,所以我建议尽可能少地使用后台bean中的业务逻辑.如果逻辑纯粹与页面的表示相关,那么将它放在辅助bean中就可以了.

我相信JSF的(许多)优势之一实际上是您可以直接在托管bean上公开域对象.因此,我强烈推荐这种<:outputText value="#{myBean.anObject.anObjectProperty}" />方法,否则你最终会在手动曝光每个属性时为自己做太多工作.此外,如果封装了所有属性,插入或更新数据时会有点混乱.在某些情况下,单个域对象可能不够用.在这些情况下,我在将它暴露在bean之前准备一个ValueObject.

编辑:实际上,如果你要封装你想要公开的每个对象属性,我建议你将UI组件绑定到支持bean,然后将内容直接注入组件的值.

就bean结构而言,我的转折点是当我强行忽略所有关于构建Web应用程序的知识并开始将其视为GUI应用程序时.JSF模仿Swing很多,因此开发Swing应用程序的最佳实践大多也适用于构建JSF应用程序.


Chr*_*ale 5

我认为你的支持 bean 最重要的事情是分离它们的逻辑。如果你有一个 CMS 系统的首页,我会认为把每一段代码都放在一个 bean 中是一种不好的做法,因为:

  1. 豆子最终会变得很大
  2. 如果其他人对登录页面进行故障排除,那么他们更容易找到他们要查找的内容,如果他们可以轻松地查找 loginBean.java 文件。
  3. 有时,您有一小部分功能与您的代码的其余部分明显不同,通过将其分开,我想您可以更轻松地重新开发/扩展此代码为更大的代码,当您已经拥有一个具有良好功能的漂亮 bean结构体。
  4. 拥有 1 个大 bean,要做到这一切,如果/当您必须执行这样的声明时,它会更加依赖内存 MyBigBean bigBean = new MyBigBean(); 而不是通过执行 LoginBean loginBean = new LoginBean(); 来使用您实际需要的 funksjonality; (如果我错了,请纠正我???)
  5. 在我看来,分离你的 bean 就像分离你的方法。你不想要一个运行超过 100 行的大方法,而是将它与处理其特定任务的新方法分开。
  6. 请记住,很可能除了您之外的其他人也必须为您的 JSF 项目工作。


至于耦合,我不认为允许 JSF 页面访问 backingbean 中对象中的属性是一个麻烦的问题。这是 JSF 内置的支持,实际上只是让阅读和构建 imo 更容易。您已经严格分离了 MVC 逻辑。通过这样做,您可以在支持bean 中为自己节省大量带有getter 和setter 的行。例如,我有一个由 Web 服务提供给我的非常大的对象,我需要在演示文稿中使用一些属性。如果我要为每个属性创建一个 getter/setter,我的 bean 将扩展至少 100 行变量和获取属性的方法。通过使用内置的 JSF 功能,我节省了时间和宝贵的代码行。

即使问题已经标记为已回答,也只是我的 2 美分。