让我们举一个基本的例子。在 servlet 应用程序中,我将拥有这些类:
- app.domain.User:域或模型 POJO,将包含字段和 getter/setter
- app.service.UserService:将包含对 User 实例进行操作的方法,例如
Register(User)
。会调用 DAO。 - app.dao.UserDao:将由服务调用,以实际在数据库中插入用户。
- app.servlets.RegisterController:一个servlet,拦截对www.app/registration的请求并调用app.service.UserService中的方法。然后它会重定向到
WEB-INF\JSPs\registration.jsp
这会照顾到 View 。
所有这些对我来说都很有意义,并且清楚地分离了问题。
从那时起,我就尝试着采用 JSF/Facelets 的思维方式。我在 SO 和其他地方浏览了许多优秀的资源,但没有任何地方可以解决这个简单的问题 - 即 dao/service/controller/view 模式如何转换为 JSF。
继续我的示例 - 我已在 eclipse 中设置了一个 JSF 项目,已将我的数据库模式转换为 "entities"
现在我想知道 - 我应该创建什么样的包,以及什么样的类王来处理用户注册?我知道我必须为 View 创建 xhtml 页面,但是 Controller 在哪里?
请不要向我指出教程 - 我知道很多教程,其中 @BalusC one - 我的问题不是让它工作而是理解模式。我见过包含“托管 bean”、“抽象外观”模式等的“ session ”包,但没有什么比好的旧 servlet 模式更有意义。
所以 - 在数据库创建的“实体”中,有一个 User.java 类,对我来说看起来像模型。该 View 将是一个 xhtml。 Controller ?
注意:这并不是在询问这些技术之间的差异,因为这里有很多重复项 - 我是在询问将非常清晰直观的 Controller /dao/服务模式清晰地转换为 JSF 框架 - 或者明确声明存在不是这样的翻译。
另请参阅:
- The NetBeans E-commerce Tutorial - 有点过时,实际上使用 JSP (!)
- An Eclipse / GlassFish / Java EE 6 Tutorial实际上使用 Servlet (!) 但至少是基于 eclipse
- JSF 2.0 tutorial with Eclipse and Glassfish我提到的 BalusC
- 一个school project具有 servlet 模式和 another bigger one与 CDI
- Understanding JSF as a MVC framework
请您参考如下方法:
JSF 2 中有两个级别的 MVC:
- Model =
@ManagedBean
,View = Facelets/xhtml,Controller =FacesServlet
(如果您只查看 jsf) - 模型 = 实体 + 服务, Controller =
@ManagedBean
, View = xhtml(如果您从整体上查看应用程序)。
JSF 应用程序中的典型包布局是相同的:
com.foo.domain.featurex.service
<- 模型com.foo.domain.featurex.model
<- 模型com.foo.presentation.featurex
<- Controller- xhtml 文件<- 查看
这里没有那么大的区别,只是你的 Controller 现在是FacesServlet
(JSF的核心)以及你的@ManagedBean/@Named
,它驻留在像 com.foo.presentation.featurex.Controller/Handler 这样的类或类似的东西。
简单注册示例:
// we talk about the big picture here, not about how jsf is built
// but how your app is built
// model
package com.foo.domain.registration.entity;
@Entity
public class User {
// fields
}
package com.foo.domain.registration.service;
// also model
@Stateless
public class RegistrationService {
@PersistenceContext
EntityManager em;
public void register(User u) {
em.persist(u);
}
}
package com.foo.presentation
// controller
@Named
@ViewScoped
public class RegistrationController {
@Inject
RegistrationService rs;
User current = new User();
public void register() {
rs.register(u);
}
// get set for current user
}
// view
// quite a lot boilerplate omitted
// form omitted which displays all the necessary field of your current user
// via value="#{registrationContoller.current.name}"
<h:commandButton value="submit" type="submit" action="#{registrationController.register}" />