JSF внедряет и обращается к Session Scoped ManagedBean в компоненте Scoped Request

У меня есть @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 );
        }
    }
}

Мой 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 в сессии.

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

2 ответа

Решение

Как сказано в комментарии, вы должны использовать инъекцию CDI. Я считаю, что это большой нет, нет, а

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

Вы не должны делать каких-либо интенсивных дел в своих добытчиках / установщиках Причина в том, что они могут быть вызваны несколько раз в фоновом режиме.

Вместо этого вам следует вызывать ваши службы с помощью метода, который называется ПОСЛЕ того, как служба была введена.

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

Вы не опубликовали свой метод аутентификации (возможно, специально).

Что касается вашей системы аутентификации, вы сказали, что будете иметь дело с этим после, но все же вам не нужно проходить через 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 а затем инициализировать его new Ferme(); в @PostConstruct тоже? или оставить как есть? // & я должен использовать методы CRUD, которые используют мой объект "Пользователь", сохраненный в сеансе в bean-компоненте @SessionScope? а затем вызвать методы в моем компоненте @RequestScoped? как это:

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

    }

}
Другие вопросы по тегам