Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Servlet/JSP MVC模式如何转换为JSF/Facelets(特别是服务和控制器部分)?_Jsp_Jsf_Jakarta Ee_Servlets_Model View Controller - Fatal编程技术网

Servlet/JSP MVC模式如何转换为JSF/Facelets(特别是服务和控制器部分)?

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

让我们举一个基本的例子。在servlet应用程序中,我将拥有以下类:

  • 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
    ,这将处理视图
所有这些对我来说都是非常有意义的,并且清楚地将这些担忧分开

从那以后,我一直试图用JSF/Facelets的思维方式来思考问题。我在这里和其他地方浏览了许多优秀的资源,但是没有任何地方可以解决这个简单的问题——即dao/service/controller/view模式如何转换为JSF

为了继续我的示例,我在eclipse中设置了一个JSF项目,将我的DB模式翻译成了
“entities”
,现在我想知道应该创建什么样的包,使用什么样的类来处理用户注册?我知道我必须为视图创建xhtml页面,但是控制器在哪里

请不要让我看教程——我知道有很多教程,其中最重要的是——我的问题不是要让它工作,而是要理解它的模式。我看到过包含“托管bean”、“抽象外观”模式等的“会话”包,但没有什么比好的旧servlet模式更有意义

因此,在DB创建的“实体”中,有一个User.java类,在我看来,它与模型类似。该视图将是一个xhtml。控制器

注意:这里并没有问这么多重复的技术之间的差异——我问的是非常清晰直观的控制器/dao/服务模式到JSF框架的清晰翻译——或者说没有这样的翻译

另见:

  • -有点过时,实际使用JSP(!)
  • 实际上使用servlet(!),但至少是基于eclipse的
  • 我提到的巴卢斯克
  • 一个具有servlet模式和CDI的

它没有。它们在概念上是不同的。 MVC使用MVC模型,jsf使用基于处理程序的模型

页面的正面是使用XHTML文件完成的。处理程序像提交表单一样处理使用输入。表单元素和处理程序之间存在绑定,通常使用getter和setter。因此,如果用户提交表单,将调用处理程序的方法,并且所有提交的数据都已准备就绪,可用于处理(感谢事件阶段的加载)

因此,您的XHTML文件将为您提供用户名和密码。调用处理程序方法。查找凭据并返回字符串,将用户转发到新页面

如前所述,您无法映射这两种技术。这就像发送电子邮件或书面信函。是的,他们传输信息,是的,这是一个中继信息系统。但它的方式是完全不同的。
在编写jsf然后切换到wicket时,这是相同的范例冲突。

JSF2中有两个MVC级别:

  • Model=
    @ManagedBean
    ,View=Facelets/xhtml,Controller=
    FacesServlet
    如果只看jsf
  • Model=Entities+Services,Controller=
    @ManagedBean
    ,View=xhtml(如果从整体上看应用程序)
JSF应用程序中的典型包布局相同:


  • 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之间的关系,但它是有效的™服务/dao/entity/controller中,因为这样可以更好地扩展。所以不要“UserService.register(User)”-什么?(请不要在这里回答-编辑你的答案)还有-你说
    Controller=@ManagedBean
    ,然后
    你的控制器现在就是FacesServlet
    -看,这一切都是令人困惑的矛盾的陈述,不是你-它们到处都是。或者
    Model=@ManagedBean
    然后
    Controller=@ManagedBean
    (asker死于困惑)这个处理器是什么?在servlets中有
    服务
    类-在这里?
    
    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) {}
            }
    }