2011-11-02 112 views
1

我的想法是:我有一个bean(UserBean),它具有一些属性可帮助我在设置为实体用户之前进行验证。我这样做是为了在整个项目中重用UserBean属性中的验证,并保持分隔层,因为我可以在堆栈溢出的许多帖子中看到这些层。 知道,我想保持MVC结构,让我们来看看我做什么至今:什么是使用JSF 2和JPA 2的项目的良好结构?

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 

} 

这是他的豆腐,的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 

} 

然后每一个与我想保持控制在一个地方的用户做的,所以我创建了用户控件豆动作:

@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 
} 

请注意,我注入userBean这里在userControl,所以当用户登录时,我救出了数据库中的值并设置在userBean中。

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

因此,在所有这些解释之后,当我尝试登录时,用户(注入的)不再保留任何值。

如果我试着这样做:

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

不要出现什么..

所以我想如果我的结构是正确的。 你们有什么想法?

回答

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}

+0

GREAAT队友!谢谢,你的建议是对的,我不得不这样做,因为在那时给了我一些NullPointerException。 你对userBean.set(用户)的想法很棒。只是一件事,在userBean中,我保留属性来进行验证,只需添加正确的?或者有一些方法来重用用户(实体)的属性? –

+0

NPE可能是由于您没有首先使用“@ ManagedProperty”而导致的。至于JSR 303验证注释,你可以直接将它们放在'User'上,但是你只需要在UserBean(或UserController)中保存第二个密码字段。实际上,有了一个合适的'Validator',你根本不需要这个字段。只有,我不会将登录表单绑定到会话范围的bean,而是绑定到UserController,而这又应该有一个'User'属性来绑定登录表单域。然后,当你登录时,在UserBean中设置找到的JPA用户实体。 – BalusC

+0

明白了!我现在要尝试这种方法,谢谢。 –

相关问题