Java 如何在我的登录页面实现多字段验证(JSF2.0)
我需要对登录页面进行多字段验证(在同一方法中同时验证多个字段)。我不知道如何正确地实施它。我在以下网站上找到了一个例子: 我在JSF部分有点困惑。有人能帮我一下吗,我遗漏了什么 页面:Java 如何在我的登录页面实现多字段验证(JSF2.0),java,jsf,jakarta-ee,jsf-2,java-ee-6,Java,Jsf,Jakarta Ee,Jsf 2,Java Ee 6,我需要对登录页面进行多字段验证(在同一方法中同时验证多个字段)。我不知道如何正确地实施它。我在以下网站上找到了一个例子: 我在JSF部分有点困惑。有人能帮我一下吗,我遗漏了什么 页面: <h:form> <p:panel> <h:outputText value="*Em@il:" /> <h:inputText id="email" value="#{securityController.email}"
<h:form>
<p:panel>
<h:outputText value="*Em@il:" />
<h:inputText id="email" value="#{securityController.email}"
required="true" />
<br />
<h:outputText value="*Password: " />
<h:inputSecret id="password" value="#{securityController.password}"
required="true">
<f:validator validatorId="loginValidator" />
</h:inputSecret>
<br />
<span style="color: red;"><h:message for="password"
showDetail="true" /></span>
<br />
<h:commandButton value="Login" action="#{securityController.logIn()}" />
</p:panel>
</h:form>
与数据库交互以检查凭据的EJB:
@Stateful(name = "ejbs/AuthentificationEJB")
public class AuthentificationEJB implements IAuthentificationEJB {
@PersistenceContext
private EntityManager em;
// Login
public boolean saveUserState(String email, String password) {
// 1-Send query to database to see if that user exist
Query query = em
.createQuery("SELECT r FROM Role r WHERE r.email=:emailparam "
+ "AND r.password=:passwordparam");
query.setParameter("emailparam", email);
query.setParameter("passwordparam", password);
// 2-If the query returns the user(Role) object, store it somewhere in
// the session
Role role = (Role) query.getSingleResult();
if (role != null && role.getEmail().equals(email)
&& role.getPassword().equals(password)) {
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().put("userRole", role);
// 3-return true if the user state was saved
System.out.println(role.getEmail() + role.getPassword());
return true;
}
// 4-return false otherwise
System.out.println(role.getEmail() + role.getPassword());
return false;
}
// Logout
public void releaseUserState() {
// 1-Check if there is something saved in the session(or wherever the
// state is saved)
if (!FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().isEmpty()) {
FacesContext.getCurrentInstance().release();
}
// 2-If 1 then flush it
}
// Check if user is logged in
public boolean checkAuthentificationStatus() {
// 1-Check if there is something saved in the session(This means the
// user is logged in)
if ((FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().get("userRole") != null)) {
// 2-If there is not a user already loged, then return false
return true;
}
return false;
}
@Override
public boolean checkCredentials(String email, String password) {
Query checkEmailExists = em
.createQuery("SELECT COUNT(r.email) FROM Role r WHERE "
+ "r.email=:emailparam AND r.password=:passwordparam");
checkEmailExists.setParameter("emailparam", email);
checkEmailExists.setParameter("passwordparam", password);
long matchCounter = 0;
matchCounter = (Long) checkEmailExists.getSingleResult();
if (matchCounter > 0) {
return true;
}
return false;
}
}
更新
已删除LoginValidator
修改后的托管bean:
@ManagedBean
@RequestScoped
public class SecurityController {
@EJB
private IAuthentificationEJB authentificationEJB;
private String email;
private String password;
private String notificationValue;
public String logIn() {
if (authentificationEJB.saveUserState(email, password)) {
notificationValue = "Dobro dosli";
return "main.xhtml";
} else {
return "";
}
}
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
UIInput emailComponent = (UIInput) component.getAttributes().get(
"emailComponent");
String email = "";
String password = "";
email = (String) emailComponent.getValue();
password = (String) value;
String emailInput = email;
String emailPatternText = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)"
+ "*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
Pattern emailPattern = null;
Matcher emailMatcher = null;
emailPattern = Pattern.compile(emailPatternText);
emailMatcher = emailPattern.matcher(emailInput);
String passwordInput = password;
String alphanumericPattern = "^[a-zA-Z0-9]+$";
Pattern passwordPattern = null;
Matcher passwordMatcher = null;
passwordPattern = Pattern.compile(alphanumericPattern);
passwordMatcher = passwordPattern.matcher(passwordInput);
if (!emailMatcher.matches() && !passwordMatcher.matches()) {
if (authentificationEJB.checkCredentials(emailInput, passwordInput) == false) {
FacesMessage msg = new FacesMessage(
"Pogresan email ili lozinka");
throw new ValidatorException(msg);
}
}
if (emailInput == null || passwordInput == null) {
FacesMessage msg = new FacesMessage("Zaboraviliste nesto");
throw new ValidatorException(msg);
}
if (passwordInput.length() <= 0 || emailInput.length() <= 0) {
FacesMessage msg = new FacesMessage("Zaboraviliste nesto");
throw new ValidatorException(msg);
}
}
// Get set methods
}
您需要通过
binding
绑定第一个组件,并将其作为要验证的组件的属性传递。当您想在托管bean中调用验证器方法时,还需要使用输入字段的validator
属性,而不是
。最后,您应该去掉bean类上的实现验证器
<h:outputText value="*Em@il:" />
<h:inputText id="email" binding="#{emailComponent}" value="#{securityController.email}" required="true"/>
<br/>
<h:outputText value="*Password: " />
<h:inputSecret id="password" value="#{securityController.password}" validator="#{securityController.validateEmailAndPassword}" required="true">
<f:attribute name="emailComponent" value="#{emailComponent}" />
</h:inputSecret>
我将LoginValidator添加为独立类而不是托管bean,并从托管bean中删除了验证方法。我在LoginValidator中得到一个NullPointerException,它说:stringpassword=(String)值;为什么呢?我也在这个类中注入EJB可以吗?这行代码不可能抛出一个NPE。这不是另一行吗?或者您的意思是值为null
?如果是后者,只需在访问/操作它之前添加一个If(password!=null)
检查。很抱歉,第27行抛出NPE:String email=emailComponent.getValue().toString();然后,emailComponent
为null
。您是否通过binding=“#{emailComponent}”
正确绑定了它?没有,我忘了。我刚加了装订。它现在工作正常,但只有当我提供了正确的凭据,当凭据错误或电子邮件字段为空时,我才能得到NPE
<h:form>
<p:panel>
<h:outputText value="*Em@il:" />
<h:inputText id="email" value="#{securityController.email}"
binding="#{emailComponent}" />
<br />
<h:outputText value="*Password: " />
<h:inputSecret id="password" value="#{securityController.password}"
validator="#{securityController.validate}">
<f:attribute name="emailComponent" value="#{emailComponent}" />
</h:inputSecret>
<br />
<span style="color: red;"><h:message for="password"
showDetail="true" /></span>
<br />
<h:commandButton value="Login" action="#{securityController.logIn()}" />
</p:panel>
</h:form>
// Login
public boolean saveUserState(String email, String password) {
// 1-Send query to database to see if that user exist
Query query = em
.createQuery("SELECT r FROM Role r WHERE r.email=:emailparam "
+ "AND r.password=:passwordparam");
query.setParameter("emailparam", email);
query.setParameter("passwordparam", password);
// 2-If the query returns the user(Role) object, store it somewhere in
// the session
try {
Role role = (Role) query.getSingleResult();
if (role != null && role.getEmail().equals(email)
&& role.getPassword().equals(password)) {
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().put("userRole", role);
// 3-return true if the user state was saved
System.out.println(role.getEmail() + role.getPassword());
return true;
}
} catch (Exception e) {
// This fix the bug that does not display the message when wrong
// password!
FacesMessage msg = new FacesMessage("Pogresan email ili lozinka");
throw new ValidatorException(msg);
}
// 4-return false otherwise
return false;
}
<h:outputText value="*Em@il:" />
<h:inputText id="email" binding="#{emailComponent}" value="#{securityController.email}" required="true"/>
<br/>
<h:outputText value="*Password: " />
<h:inputSecret id="password" value="#{securityController.password}" validator="#{securityController.validateEmailAndPassword}" required="true">
<f:attribute name="emailComponent" value="#{emailComponent}" />
</h:inputSecret>
public void validateEmailAndPassword(FacesContext context, UIComponent component, Object value) throws ValidatorException {
UIInput emailComponent = (UIInput) component.getAttributes().get("emailComponent");
String email = (String) emailComponent.getValue();
String password = (String) value;
// ...
}