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