【发布时间】:2015-10-03 14:55:51
【问题描述】:
我有一个@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 );
}
}
}
我的登录豆:
@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);
}
}
登录.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 的列表,用户ID 存储在会话中的对象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>
【问题讨论】:
-
我会使用 CDI 而不是 JSF(
@Named而不是@ManagedBean、@Inject而不是@ManagedProperty和范围 - 这是较新的技术)并且我不会将@EJB注入@RequestScoped但我会在@SessionScoped中创建此方法并委托调用它。使用@Stateless,这不是问题,但如果您使用@Stateful,就会出现问题。 -
@Geinmachi 谢谢你的建议。因此,如果我确实理解了,您是说我不应该在 SessionScoped 和 RequestScoped 中都注入 EJB,而是应该将会话中使用“用户”对象的所有方法创建到 SessionScoped 中,然后我可以调用它们在 RequestScoped Bean 中?
-
是的,这是关于将
@Stateful注入@RequestScoped的线程,因此您可以了解我在说什么。 stackoverflow.com/questions/4562941/… -
@Geinmachi 好的,非常感谢您的帮助!
-
TL;DR : 将范围更广的 JSF 托管 bean 注入到范围更窄的 JSF 托管 bean 中是一种合法的游戏。然而,反过来是不真实的。换句话说,将会话范围的 JSF 托管 bean 注入请求范围的 JSF 托管 bean 是完全合法的。
标签: session jsf jakarta-ee code-injection requestscope