JSF 在 Request Scoped Bean 中注入和访问 Session Scoped ManagedBean

JSF injecting and accessing Session Scoped ManagedBean in a Request Scoped Bean

我有一个@SessionScoped ManagedBean,我已将其注入@RequestScoped 以访问存储在会话中的用户。我的代码正在运行我只想知道我是否使用了良好的做法,如果没有,请告诉我哪里出了问题?因为我是 JSF 的新手,不想从头学一些烂代码,先谢谢大家了。

我的实体实用程序:

    @Entity
    public class Utilisateur {

    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    private Long      id;
    @NotNull( message = "Veuillez saisir une adresse email" )
    @Pattern( regexp = "([^.@]+)(\.[^.@]+)*@([^.@]+\.)+([^.@]+)", 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..
    }

我的实体工厂:

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

我的登录Bean:

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

如评论中所述,您应该使用 cdi 注入。我相信这也是一个很大的禁忌:

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

您应该在您的 getters/setters 中做任何业务密集型的事情。原因是那些可以在后台多次调用。

相反,您应该在注入服务后调用的方法中调用您的服务。

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

您没有 post 您的身份验证方法(不过可能是故意的)。

保护您的 Auth 系统,您说您将在之后处理这个问题,但您仍然不需要通过 DAO 处理它。您应该在文档中阅读有关 JAAS 的内容,了解如何自动处理此问题,然后您无需通过服务即可对 bean 中的用户进行身份验证。即:Request.login(username, password) 如果我没记错的话。不过,您必须阅读有关该主题的内容,在对用户进行身份验证时,您应该使用 hash + salt。

@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 中使用使用存储在会话中的 "User" 对象的 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;

    }

}