理解JSF作为MVC框架

60

我正在学习JSF,但对于它为什么是MVC框架感到相当困惑(或者至少哪些部分属于哪个字母)。

我看了这个问题:What components are MVC in JSF MVC framework?

我在那里读到,如果不从总体上看,模型就是实体,视图就是XHTML代码,控制器就是托管bean。嗯...好吧,但是视图很常依赖于进行进一步的业务逻辑调用,例如返回一组实体,这个描述是否仍然适用?

我读过的一本书将其描述为托管bean是某种“消息”传递者,Faces Servlet(控制器)使用它来调用业务层(模型),然后XHTML代码是视图。

有这么多的解释和差异,所以我不知道该如何理解它。

4个回答

111

JSF和许多其他Web框架之所以常常不清楚哪些部分对应于MVC的哪个部分,部分原因在于MVC模式最初是为桌面应用程序设计的。

在桌面应用程序中,节点M、V和C是最大连接图,这意味着每个部分都可以与其他每个部分通信。例如,如果模型发生更改,它可以将此更改推送到视图。如果桌面应用程序中存在多个视图表示,则尤其明显。更改一个视图会实时看到另一个视图更新。

由于Web应用程序的客户端/服务器和请求/响应性质,经典MVC不适用于大多数Web框架。

具体而言,在JSF中,映射如下:

  • 模型 - 服务/DAO加上它们生成和消耗的实体。入口点是托管Bean,但在Java EE(其中JSF是一部分)中,这些工件通常由EJB和JPA分别实现。
  • 视图 - UI组件及其组合成完整页面。这完全属于JSF领域,并由JSF的UIComponent和Facelets分别实现。
  • 控制器 - 处理来自用户的命令和传入数据,将其路由到正确的部分并选择要显示的视图的交通警察。在JSF中,你不编写这个控制器,而是框架已经提供了它(它是FacesServlet)。

特别是最后一部分经常不被很好地理解:在JSF中,你不实现一个控制器。因此,备份Bean或任何其他类型的托管Bean不是控制器。

第一部分(模型)通常也不是很清楚。业务逻辑可能通过 EJB 和 JPA 实现,但从 JSF 的角度来看,由值绑定引用的所有内容都属于模型。这也是 JSF 生命周期阶段中一个命名的来源:Update Model。在这个阶段中,JSF 将数据从 UI 组件推入模型。从这个意义上说,(JSF)管理的 Bean 就是模型。
尽管 JSF 本身并没有明确定义这个概念,但经常使用的 managed bean 具有特定的重复使用方式,称为 backing bean。
对于 JSF,backing bean 仍然是模型,但实际上它是处于模型、视图和控制器中间的一个管道元素。由于它执行了一些可视作某些控制器任务的工作,因此常常被错误地认为是控制器。但是,如前所述,这并不正确。它也可以执行一些模型任务,并偶尔执行一些视图逻辑。
另请参见:

2
作为一个管道组件,支持Bean通常被注入一个服务(Service),从中获取一个或多个实体。这些实体确实会被保留。通过getter方法可以返回整个实体。视图组件绑定实体的各个属性。基本上,支持Bean意味着服务代码保持“纯净”,并且数据在Bean的范围内缓存(通常是视图范围或请求范围)。 - Arjan Tijms
1
@RodmarConde 嗯,可能有一点,但更常见的情况是将某些客户端代码视为视图,而 Web 服务只是服务的路径。 - Arjan Tijms
1
@ArjanTijms,你提供的答案就像是一枪爆头,非常容易准确地抓住重点。 - kark
3
您提供的链接已失效:http://www.sts.tu-harburg.de/pw-and-m-theses/2007/maab07.pdf。 - Marc Bouvier
@MarcBouvier 你可能会觉得这个链接有帮助:http://www.tutorialspoint.com/jsf/jsf_architecture.htm - dngfng
显示剩余3条评论

8
以最简单的形式来说,它是:
  • Model:用于持久化(Hibernate、JPA等)和数据建模(Java Beans)的任何内容。
  • View:xhtml、jsp等。
  • Controller:Managed Beans。
JSF让您有能力控制请求/响应。创建模型/视图的方式与框架MVC概念不直接相关,这只是选择的问题。MVC概念与代码组织有关。
类比而言,Struts是一个MVC框架,但它主要作为控制器使用。
我认为我的翻译可以帮助您更好地澄清想法。

Java Beans和Managed Beans有什么区别? - Koray Tugay
2
嗨@KorayTugay,Java Beans是具有getter和setter以及默认构造函数的简单类,而Managed Bean是轻量级容器管理的对象。 Java Beans:https://en.wikipedia.org/wiki/JavaBean/index.html Managed Beans:http://docs.oracle.com/javaee/6/tutorial/doc/gjaam.html#gjacb - axcdnt
谢谢,上面的回答明确表示托管bean不是控制器...所以这还有点令人困惑。 - Koray Tugay
如果可能的话,您能用简单的英语解释一下“使用持久性”是什么意思吗? - Koray Tugay
1
假设你要使用持久层,那么你应该定义自己的模型类,无论是ORM解决方案还是JDBC。假设你选择了JDBC,你会有像"Person.java"这样的类,其中包含名称和年龄等属性。在持久化之前,你需要设置它的值(如名称、年龄等)。通常情况下,这将被称为“实体”或通用模型。如果你选择了ORM解决方案(如Hibernate),你应该使用注释(@Entity)或XML文件来映射你的类。希望你能理解,这只是一个相当肤浅的解释。 - axcdnt

7
有趣的是,托管bean的想法既可以用作模型(MVC模式),也可以用作控制器(中介控制器MVC模式,也称为模型-视图-适配器),其中模型和视图不直接交互。
在后一种情况下,路由机制不是控制器,因为业务逻辑包含在托管bean中,而模型严格是域模型。我们有:
- 模型 - 包含域模型,在大多数情况下表示数据库中的表,通过DAO持久化。 - 视图 - UI组件,连接到bean; - 控制器 - 包含业务逻辑并处理视图和模型之间通信的托管bean。
我认为有些人将中介控制器MVC误解为普通MVC,这导致了不同的解释。

2

我认为这里的所有答案都是正确的。但是对我而言,混淆的主要原因来自于将来自框架(例如JSF)的MVC组件定义与您在应用程序设计中定义的模型和控制器组件混合在一起。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接