使用JSF 2和JPA 2的项目有什么好的结构?

时间:2011-11-02 14:44:10

标签: model-view-controller jsf jpa jsf-2 jpa-2.0

我的想法是:我有一个bean( UserBean ),它有一些属性可以帮助我在设置实体用户之前验证。我这样做是为了在整个项目的 UserBean 属性中重用validate并保持层分离,因为我可以在堆栈溢出中的很多帖子中阅读>。 知道我想保留MVC结构,让我们看看到目前为止我做了什么:

structure

(对不起我认为理解我的问题会更容易理解的大图片)

这是我的用户(在实体包中):

@Entity
@Table(name="user")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private int id;

    private String email;

    private String password;

    private int reputation;

    //bi-directional one-to-one association to Company
    @OneToOne(mappedBy="user", cascade={CascadeType.ALL})
    private Company company;

    //bi-directional many-to-one association to Location
    @OneToMany(mappedBy="user")
    private List<Location> locations;

    //bi-directional one-to-one association to Person
    @OneToOne(mappedBy="user")
    private Person person;

    //bi-directional many-to-one association to Product
    @OneToMany(mappedBy="user")
    private List<Product> products;

    //bi-directional many-to-one association to UserType
    @ManyToOne
    @JoinColumn(name="type")
    private UserType userType;

    //bi-directional many-to-one association to UserPhone
    @OneToMany(mappedBy="user")
    private List<UserPhone> userPhones;

    //bi-directional many-to-one association to UserPicture
    @OneToMany(mappedBy="user")
    private List<UserPicture> userPictures;

    //bi-directional many-to-one association to UserSocialNetwork
    @OneToMany(mappedBy="user")
    private List<UserSocialNetwork> userSocialNetworks;

       // getters and setters

}

这是他的bean,UserBean(在bean.entity包中):

@ManagedBean
@SessionScoped
public class UserBean implements Serializable {
    private static final long serialVersionUID = -1626847931067187536L;

    private int id;

    @NotNull(message="informe seu e-mail")
    @Email(message="e-mail inválido")
    private String email;

    @NotNull(message = "6 dígitos no mínimo")
    @Size(min = 6, max = 128, message = "6 dígitos no mínimo")
    private String password;

    @NotNull(message = "6 dígitos no mínimo")
    @Size(min = 6, max = 128, message = "6 dígitos no mínimo")
    private String password_2;

    private int reputation;

    private UserType userType;

    private List<UserPhoneBean> userPhones;

    private List<UserPicture> userPictures;

    private List<UserSocialNetwork> userSocialNetworks;

    @AssertTrue(message = "senhas diferentes")
    public boolean isPasswordsEquals() {
        return password.equals(password_2);
    }

        // getters and setters

}

然后每个与用户有关的动作我想将控件保存在一个地方,所以我创建了 UserControl bean:

@ManagedBean(name="userc")
@ViewScoped
public class UserControl implements Serializable {
    private static final long serialVersionUID = -1626847931067187536L;

    @EJB EaoUser eaoUser;
    @EJB EaoPerson eaoPerson;

    @ManagedProperty("#{userBean}")
    private UserBean user;

    @ManagedProperty("#{personBean}")
    private PersonBean person;

    private UserBean ub;
    private PersonBean pb;

    private View view;


    public UserControl() {
        ub = new UserBean();
        pb = new PersonBean();
        view = new View();
    }

    public String login(){
        List<User> list = eaoUser.findByEmail(ub.getEmail());
        User u = list.get(0);

            if (Crypto.check(ub.getPassword(), u.getPassword())){
                HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false); 
                session.setAttribute("authenticated", true);

                user = new UserBean();
                user.setId(u.getId());
                user.setEmail(u.getEmail());
                user.setPassword(u.getPassword());
                user.setReputation(u.getReputation());

                user.setUserType(u.getUserType());

                if (u.getUserType().getId() == 10){
                    Person p = eaoPerson.find(u.getId());

                    if (p != null){
                        person = new PersonBean();
                        person.setName(p.getName());
                        person.setSurname(p.getSurname());
                        person.setBirthdate(p.getBirthdate());
                        person.setGender(p.getGender());
                    }
                }

                for (UserPhone up : u.getUserPhones()){
                    user.getUserPhones().add(new UserPhoneBean(up.getId(), up.getPhone()));
                }

                user.setUserPictures(u.getUserPictures());
                user.setUserSocialNetworks(u.getUserSocialNetworks());

            }else{
                view.imageError();
                view.setStatus("e-mail ou senha incorretos");
                view.setPopup(true);

                return "#";
            }

        return "secured/user/home?faces-redirect=true";
    }
        // others method, getters and setters
}

请注意,我在 userControl 中注入 userBean ,因此当用户登录时,我会从数据库中获取值并在userBean中进行设置。

我创建属性用户 ub ,因为当我尝试使用用户进行验证时,验证似乎不起作用,我猜这是因为他已经注射了(只是猜测)。

所以,经过所有这些解释,当我尝试登录时,用户(注入的是)不再保留任何值。

如果我尝试这样做:

Welcome, <h:outputText value="#{userc.user.email}" />

不要出现任何事情......

所以我想知道我的结构是否正确。 你们对此有什么看法?

1 个答案:

答案 0 :(得分:1)

该问题与项目结构无关。

真正的问题在于login()方法:

user = new UserBean();

您通过手动创建的bean覆盖了JSF注入的托管bean。这个不会被JSF使用,并在视图离开后丢失。此时JSF注入的托管属性user不应该是null。您不需要自己创建它。完全删除该行。

但是您还有其他更大的问题,即将属性从一个User复制到另一个User是完全没必要的。基本上,您需要向User类添加UserBean属性,然后执行user.setUser(user);。这种方式由#{userBean.user.email}提供。我只能重命名这个或那个,以便EL代码更有意义。您希望以#{user.current.email}#{login.user.email}#{auth.user.email}等方式结束。