2015-10-03 77 views
1

我有一個@SessionScoped ManagedBean,我注入了@RequestScoped來訪問存儲在會話中的用戶。我的代碼正在工作我只想知道我是否正在使用一種良好的習慣,如果不是,你能告訴我什麼是錯的嗎?因爲我是JSF的新手,我不想從一開始就學習一些不好的代碼,所以非常感謝你。JSF注入並訪問請求作用域bean中的會話作用域ManagedBean

我的實體Utilisateur:

@Entity 
    public class Utilisateur { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long  id; 
    @NotNull(message = "Veuillez saisir une adresse email") 
    @Pattern(regexp = "([^[email protected]]+)(\\.[^[email protected]]+)*@([^[email protected]]+\\.)+([^[email protected]]+)", message = "Merci de saisir une adresse mail valide") 
    private String email; 
    @Column(name = "mot_de_passe") 
    @NotNull(message = "Veuillez saisir un mot de passe") 
    @Pattern(regexp = ".*(?=.{8,})(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).*", message = "Le mot de passe saisi n'est pas assez sécurisé") 
    private String motDePasse; 
    @NotNull(message = "Veuillez saisir un nom d'utilisateur") 
    @Size(min = 3, message = "Le nom d'utilisateur doit contenir au moins 3 caractères") 
    private String nom; 
    @Column(name = "date_inscription") 
    private Timestamp dateInscription; 
//getters .. setters.. 
    } 

我的實體Ferme酒店:

@Entity 
public class Ferme { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id_ferme") 
    private Long  id_ferme; 
    @Column(name = "nom_ferme") 
    private String nom_ferme; 
    @ManyToOne 
    @JoinColumn(name = "utilisateur_id") 
    private Utilisateur utilisateur; 

//getters .. setters.. 

} 

我@Statless DAO:

@Stateless 
public class UtilisateurDao { 
@PersistenceContext(unitName = "myBD_PU") 
    private EntityManager  em; 

public List<Ferme> lister(Utilisateur user) throws DAOException { 
     try { 
      TypedQuery<Ferme> query = em.createQuery("SELECT u FROM Ferme u WHERE u.utilisateur = :userid", Ferme.class); 
      query.setParameter("userid", user); 

      return query.getResultList(); 
     } catch (Exception e) { 
      throw new DAOException(e); 
     } 
    } 
} 

我LoginBean:

@ManagedBean 
    @SessionScoped 
    public class LoginBean implements Serializable { 

     private static final long serialVersionUID = 1L; 

     private String email,mdp; 
     private Utilisateur user; 
     private boolean LoggedIn; 
     @EJB 
     UtilisateurDao utilisateurDao; 

     // getters .. setters 



public String authentification() { 

    if (utilisateurDao.login(email, mdp) != null) { 
     user = utilisateurDao.login(email, mdp); 
     LoggedIn = true; 
     return "listeFermes.xhtml?faces-redirect=true"; 
    } 
    LoggedIn = false; 
    FacesMessage message = new FacesMessage("E-mail ou Mot de passe incorrecte!"); 
    FacesContext.getCurrentInstance().addMessage(null, message); 

    return ""; 
} 

public String logout() { 
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); 
    return "/login.xhtml?faces-redirect=true"; 
} 
    } 

我ListeFermesBean:

@ManagedBean 
    @RequestScoped 
    public class ListeFermesBean implements Serializable{ 

     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 

     @ManagedProperty(value="#{loginBean}") 
     private LoginBean loginBean; 

     @EJB 
     UtilisateurDao utilisateurDao; 

     private Utilisateur user; 
     private List<Ferme> liste; 

public List<Ferme> getListe() { 
     liste = new ArrayList<Ferme>(); 
     user = loginBean.getUser(); 
     return liste = utilisateurDao.lister(user); 
    } 
    } 

Login.xhtml:

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> 
    ... 
    ... 
     <h:form id="Login"> 
     <fieldset> 
      <legend>Login</legend> 
      <h:outputLabel for="email">Adresse email <span class="requis">*</span></h:outputLabel> 
      <h:inputText id="email" value="#{loginBean.email}" size="20" maxlength="60"> 
      </h:inputText> 
      <h:message id="emailMessage" for="email" errorClass="erreur" /> 
      <br /> 

      <h:outputLabel for="motdepasse">Mot de passe <span class="requis">*</span></h:outputLabel> 
      <h:inputSecret id="motdepasse" value="#{loginBean.mdp}" size="20" maxlength="20"> 
      </h:inputSecret> 
      <h:message id="motDePasseMessage" for="motdepasse" errorClass="erreur" /> 
      <br /> 

      <h:messages globalOnly="true" infoClass="erreur" /> 

      <h:commandButton value="Login" action="#{loginBean.authentification}" styleClass="sansLabel"> 
      </h:commandButton> 
      <br /> 
      <h:commandButton value="Logout" action="#{loginBean.logout}" styleClass="sansLabel" /> 
      <br /> 
      <h:link value="Inscrivez-vous" outcome="inscription" /> 



      </fieldset> 
     </h:form> 
    </h:body> 
</html> 

最後的listeFermes.xhtml頁面從listeFermesBean通過存儲在會話對象User用戶ID將顯示在列表中。

<!DOCTYPE html> 
<html lang="fr" 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:c="http://java.sun.com/jstl/core"> 
    <h:head> 
     <title>SUCCES</title> 
    </h:head> 
    <h:body> 

     <ui:fragment rendered= "#{!loginBean.loggedIn}"> 
     Not logged ! 
     </ui:fragment> 
     <ui:fragment rendered= "#{loginBean.loggedIn}"> 
     Welcome : #{loginBean.user.nom} <br /> 
     E-mail : #{loginBean.user.email} <br /> 

     <table border="1"> 
     <tr> 
      <td>Nom Ferme</td> 
      <td>Nom User</td> 
      <td>ID User</td> 
     </tr> 
     <c:forEach items="#{ listeFermesBean.liste }" var="x"> 
     <tr> 
      <td>#{x.nom_ferme}</td> 
      <td>#{x.utilisateur.nom}</td> 
      <td>#{x.utilisateur.id}</td> 
     </tr> 
     </c:forEach>  
     </table> 
     </ui:fragment> 

    </h:body> 
</html> 
+0

我會用CDI,而不是JSF('@ Named',而不是'@ ManagedBean','@ Inject',而不是'@ ManagedProperty'和範圍 - 它是較新的技術),我不會在@ RequestScoped中注入@ @ EJB,但是我會在@ SessionScoped中創建這個方法並委託對它的調用。用'@ Stateless'這個不是問題,但是如果你使用'@ Stateful'的話。 – Geinmachi

+0

@Geinmachi謝謝你的建議。所以,如果我明白了,你是說我不應該在SessionScoped和RequestScoped中注入EJB,而是應該創建所有使用會話中的「User」對象到SessionScoped中的方法,然後我可以調用他們在RequestScoped Bean中? – dwix

+0

是的,這裏是關於向'@ RequestScoped'注入'@ Stateful'的線程,這樣你就可以知道我在說什麼了。 http://stackoverflow.com/questions/4562941/problem-using-stateful-ejb-in-managedbean-with-requestscope – Geinmachi

回答

2

正如評論中所說,你應該使用cdi injection。我相信這是一個很大的不,不和:

public List<Ferme> getListe() { 
     liste = new ArrayList<Ferme>(); 
     user = loginBean.getUser(); 
     return liste = utilisateurDao.lister(user); 
    } 

你應該做任何業務密集的東西在你的getter/setter方法。原因是那些可以在後臺多次調用。

相反,您應該在服務注入後調用的方法中調用您的服務。

@PostConstruct 
public void init(){ 
    listeFerm = utilisateurDao.lister(user); 
} 
public List<Ferm> getListFerm(){ 
    return listFerm; 
} 

您沒有發佈您的auth方法(可能是故意的)。

Reguarding你的驗證系統,你說你會處理這個後,但你仍然不需要通過DAO的。你應該閱讀關於如何自動處理這個文檔的JAAS,然後你不需要通過一個服務,你可以在bean中驗證用戶。即:Request.login(username, password)如果我的記憶爲我服務的權利。不過,您必須閱讀有關該主題的內容,但在驗證用戶時應使用hash + salt。

+0

謝謝你的回答,我的loginBean現在是這樣的(在上面的新答案中)我不能在這個評論中加入它。 – dwix

+0

如果這就是你正在談論的問題,我已經重新發布了我的認證方法(在上面的新答案中)。在此先感謝:) – dwix

+0

@dwix您打算將密碼存儲爲純文本嗎?因爲這就是你失去每個用戶密碼的原因。當您發佈其他代碼時,您應該編輯您的主要問題。我要在你的新代碼中修改我的文章。然後你可以接受我的答案,因爲它幫助你(點擊v)。互聯網點也歡迎upvote。 – Ced

0
@Named 
@SessionScoped 
public class LoginBean implements Serializable { 

    private static final long serialVersionUID = 1L; 

    private String email,mdp; 
    private Utilisateur user; 
    private boolean LoggedIn; 
    private List<Ferme> liste; 
    private Ferme ferme = new Ferme(); 
    @Inject 
    UtilisateurDao utilisateurDao; 



    public Ferme getFerme() { 
     return ferme; 
    } 
    public void setFerme(Ferme ferme) { 
     this.ferme = ferme; 
    } 
    public void setListe(List<Ferme> liste) { 
     this.liste = liste; 
    } 
    public String getEmail() { 
     return email; 
    } 
    public void setEmail(String email) { 
     this.email = email; 
    } 
    public String getMdp() { 
     return mdp; 
    } 
    public void setMdp(String mdp) { 
     this.mdp = mdp; 
    } 
    public Utilisateur getUser() { 
     return user; 
    } 
    public void setUser(Utilisateur user) { 
     this.user = user; 
    } 
    public boolean isLoggedIn() { 
     return LoggedIn; 
    } 
    public void setLoggedIn(boolean loggedIn) { 
     LoggedIn = loggedIn; 
    } 


    public String authentification() { 

     if (utilisateurDao.login(email, mdp) != null) { 
      user = utilisateurDao.login(email, mdp); 
      LoggedIn = true; 
      return "listeFermes.xhtml?faces-redirect=true"; 
     } 
     LoggedIn = false; 
     FacesMessage message = new FacesMessage("Wrong E-mail or Password!"); 
     FacesContext.getCurrentInstance().addMessage(null, message); 

     return ""; 
    } 



public String logout() { 
      FacesContext context = FacesContext.getCurrentInstance(); 
      context.addMessage(null, new FacesMessage("You are disconnected!")); 
      ExternalContext externalContext = context.getExternalContext(); 
      externalContext.getFlash().setKeepMessages(true); 
      externalContext.invalidateSession(); 

      return "/login.xhtml?faces-redirect=true"; 
     } 

    public void deleteFerme(int id) { 
      utilisateurDao.supprimerFerme(user, id); 
     } 

     public void addFerme() { 
      utilisateurDao.creerFerme(ferme, user); 
     } 

     public List<Ferme> getListe() { 
     return liste; 
    } 

    @PostConstruct 
    public void init(){ 
     liste = utilisateurDao.lister(user); 
    } 

//我應該聲明我Ferme,然後用來初始化它在@PostConstruct new Ferme();嗎?或者讓它保持原樣? // &我應該使用使用存儲在會話中的「用戶」對象,在@SessionScope bean中的CRUD方法嗎?然後調用我的@RequestScoped bean中的方法?像這樣:

@SessionScope 
public class LoginBean { 

    .. 
    .. 
    public void addFerme() { 
    utilisateurDao.creerFerme(ferme, user); 
} 
    } 


    //////..... and then in the RequestScoped bean : 

@RequestScoped 
    .. 
    .. 
    @Inject 
    private LoginBean loginBean; 

    public void addFerme() { 

      loginBean.addFerme(); 
     } 

//登錄方法

@Stateless 
public class UtilisateurDao { 

@PersistenceContext(unitName = "MyBD_PU") 
    private EntityManager  em; 

public Utilisateur login(String email, String mdp) throws DAOException { 
     Utilisateur user = null; 
     Query requete = em.createQuery(JPQL_LOGIN); 
     requete.setParameter(PARAM_EMAIL, email).setParameter(PARAM_PWD, mdp); 

     try { 
      user = (Utilisateur) requete.getSingleResult(); 
      if (user!=null) { 
       return user; 
      } 
      return null; 
     } catch (NoResultException e) { 
      return null; 
     } catch (Exception e) { 
      FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), null); 
      FacesContext facesContext = FacesContext.getCurrentInstance(); 
      facesContext.addMessage(null, message); 
     } 
     return user; 

    } 

} 
相關問題