2011-11-02 60 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

明白了!我現在要嘗試這種方法,謝謝。 –

相關問題