Servlet/JSP MVC模式如何转换为JSF/Facelets(特别是服务和控制器部分)?
让我们举一个基本的例子。在servlet应用程序中,我将拥有以下类:Servlet/JSP MVC模式如何转换为JSF/Facelets(特别是服务和控制器部分)?,jsp,jsf,jakarta-ee,servlets,model-view-controller,Jsp,Jsf,Jakarta Ee,Servlets,Model View Controller,让我们举一个基本的例子。在servlet应用程序中,我将拥有以下类: app.domain.User:域或模型POJO将包含字段和getter/setter app.service.UserService:将包含对用户实例进行操作的方法,例如注册(用户)。我会叫刀 app.dao.UserDao:服务将调用它来实际(比如)在数据库中插入用户 app.servlets.RegisterController:一个servlet拦截对www.app/registration的请求并调用app.ser
- app.domain.User:域或模型POJO将包含字段和getter/setter
- app.service.UserService:将包含对用户实例进行操作的方法,例如
。我会叫刀注册(用户)
- app.dao.UserDao:服务将调用它来实际(比如)在数据库中插入用户
- app.servlets.RegisterController:一个servlet拦截对www.app/registration的请求并调用app.service.UserService中的方法。然后,它将重定向到
,这将处理视图WEB-INF\JSPs\registration.jsp
“entities”
,现在我想知道应该创建什么样的包,使用什么样的类来处理用户注册?我知道我必须为视图创建xhtml页面,但是控制器在哪里
请不要让我看教程——我知道有很多教程,其中最重要的是——我的问题不是要让它工作,而是要理解它的模式。我看到过包含“托管bean”、“抽象外观”模式等的“会话”包,但没有什么比好的旧servlet模式更有意义
因此,在DB创建的“实体”中,有一个User.java类,在我看来,它与模型类似。该视图将是一个xhtml。控制器
注意:这里并没有问这么多重复的技术之间的差异——我问的是非常清晰直观的控制器/dao/服务模式到JSF框架的清晰翻译——或者说没有这样的翻译
另见:
- -有点过时,实际使用JSP(!)
- 实际上使用servlet(!),但至少是基于eclipse的
- 我提到的巴卢斯克
- 一个具有servlet模式和CDI的
在编写jsf然后切换到wicket时,这是相同的范例冲突。JSF2中有两个MVC级别:
- Model=
,View=Facelets/xhtml,Controller=@ManagedBean
如果只看jsfFacesServlet
- Model=Entities+Services,Controller=
,View=xhtml(如果从整体上看应用程序)@ManagedBean
以下是我最后做的事-服务,玩道:com.foo.domain.featurex.service
控制器-由package app.service; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; import app.entities.User; @Stateless public class UserService { @PersistenceContext private EntityManager em; public User register(User u) { // TODO : transactions, sql injection // https://stackoverflow.com/q/21640369/281545 em.persist(u); // em.flush(); // not needed return u; } public boolean isUsernameUnique(String username) { Query query = em .createNativeQuery("SELECT r1_check_unique_username(?)"); short i = 0; query.setParameter(++i, username); return (boolean) query.getSingleResult(); } }
注意这些包,我使用服务作为DAO。不清楚EJB与CDI之间的关系,但它是有效的™另外,我个人认为COM.Fo.doMaNe.Frimulx.Service和C..Fo.PrimtIt.Futuxx是一个巨大的反模式。为什么不在应用程序的逻辑中命名包呢?com.foo.featurex.presentation和com.foo.featurex.serviceWell在域/业务和演示中划分项目是人们习惯的。然而,我不会坚持这种分离。更重要的是在特性中划分组件,而不仅仅是在
中,因为这样可以更好地扩展。所以不要“UserService.register(User)”-什么?(请不要在这里回答-编辑你的答案)还有-你说服务/dao/entity/controller
,然后Controller=@ManagedBean
-看,这一切都是令人困惑的矛盾的陈述,不是你-它们到处都是。或者你的控制器现在就是FacesServlet
然后Model=@ManagedBean
(asker死于困惑)这个处理器是什么?在servlets中有Controller=@ManagedBean
服务
类-在这里?
package app.service; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; import app.entities.User; @Stateless public class UserService { @PersistenceContext private EntityManager em; public User register(User u) { // TODO : transactions, sql injection // https://stackoverflow.com/q/21640369/281545 em.persist(u); // em.flush(); // not needed return u; } public boolean isUsernameUnique(String username) { Query query = em .createNativeQuery("SELECT r1_check_unique_username(?)"); short i = 0; query.setParameter(++i, username); return (boolean) query.getSingleResult(); } }
package app.controllers; import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.bean.ViewScoped; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; import javax.persistence.NoResultException; import app.entities.User; import app.service.UserService; @ManagedBean @ViewScoped public class UserController { // https://stackoverflow.com/a/10691832/281545 private User user; @EJB // do not inject stateful beans (?) // @Inject private UserService service; public User getUser() { return user; } @PostConstruct void init() { // https://stackoverflow.com/questions/3406555/why-use-postconstruct user = new User(); } public String login() { return null; } public String register() { FacesContext context = FacesContext.getCurrentInstance(); user = service.register(user); if (user.getIduser() == 0) { context.addMessage(null, new FacesMessage( FacesMessage.SEVERITY_ERROR, "Registration failed", null)); return null; } context.getExternalContext().getSessionMap().put("user", user); return "/index.xhtml?faces-redirect=true"; } public String logout() { return null; } @ManagedBean @RequestScoped public static class UniqueUsernameValidator implements Validator { @EJB private UserService service; @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { if (value == null) return; // Let required="true" handle, if any. try { if (!service.isUsernameUnique((String) value)) { throw new ValidatorException(new FacesMessage( FacesMessage.SEVERITY_ERROR, "Username is already in use.", null)); } } catch (Exception e) {} } }