2011-04-13 31 views
0

我有一个由JSF页面+托管bean + EJB组成的登录机制,但它的工作正常,但唯一的错误是,当我看不到错误消息密码输入错误。有任何想法吗?当密码错误时,登录表单不显示验证消息

当输入密码错误,这是我所得到的在浏览器中:

enter image description here

我能避免这种情况,如果我不扔在catch一个ValidationException在EJB(见EJB代码下面),但是当密码输入错误时,我根本没有看到任何验证消息。

这是在页面代码的形式:

<h:form> 
    <p:panel>     
       <h:outputText value="*[email protected]:" /> 
       <h:inputText id="email" value="#{securityController.email}" binding="#{emailComponent}"/>     
       <br/> 
       <h:outputText value="*Lozinka: " /> 
       <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> 

这是managedBean代码:

@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("Pogresan email ili lozinka"); 
      throw new ValidatorException(msg); 
     } 
     if (passwordInput.length() <= 0 || emailInput.length() <= 0) { 
      FacesMessage msg = new FacesMessage("Pogresan email ili lozinka"); 
      throw new ValidatorException(msg); 
     } 
    } 

    public String getEmail() { 
     return email; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public String getNotificationValue() { 
     return notificationValue; 
    } 

    public void setNotificationValue(String notificationValue) { 
     this.notificationValue = notificationValue; 
    } 
} 

这是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 
     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) { 
          FacesMessage msg = new FacesMessage("Pogresan email ili lozinka"); 
      throw new ValidatorException(msg); 
     } 
     // 4-return false otherwise 
     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; 
    } 
} 
代码

这里在EJB中,我认为我犯了一个错误,如果我在catch块中抛出ValidationException,因为我认为显示err或者前端的消息应该是托管bean的任务。我不明白为什么表单不显示错误,因为当密码错误时字段为空(当电子邮件错误时,它会正确显示验证消息)。

更新

改变了saveUserState()方法在EJB到:

// 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 
    List<Object> tmpList = query.getResultList(); 
    if (tmpList.isEmpty() == false) { 
     Role role = (Role) tmpList.get(0); 
     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 
    return false; 
} 

支票凭证方法:

public boolean checkCredentials(String email, String password) { 
    Query checkEmailExists = em 
      .createQuery("SELECT COUNT(r) FROM Role r WHERE r.email=:emailparam AND r.password=:passwordparam"); 
    checkEmailExists.setParameter("emailparam", email); 
    checkEmailExists.setParameter("passwordparam", password); 
    int matchCounter = 0; 
    matchCounter = checkEmailExists.getResultList().size(); 
    if (matchCounter == 1) { 
     return true; 
    } 
    return false; 
} 

回答

1

你不应该抛出的JSF ValidatorException内的EJB方法,但是在JSF validate()方法中。

我不确定在导致此异常的EJB中出了什么问题,可能getSingleResult()根本没有返回单个结果(因此为零或多个)。您需要相应地更改/处理此问题,方法是使用getResultList()或修改您的数据模型为什么用户没有单一角色。我想你只需要getResultList(),因为你显然允许null结果。

+0

我现在使用getResultsList(),并且我还检查了查询返回的内容。返回的只有一个Role实例。当authentificationEJB.checkCredentials(emailInput,passwordInput)被评估为false时,validate方法已经抛出Validation异常。我不明白错误在哪里。我的数据模型我认为是可以的。我有3个用户(买方,卖方和管理员),他们每个人都与角色有一对一的关系。角色实体包含变量email和密码。 P.S(当我检查证书时,查询只能访问角色实体) – sfrj 2011-04-13 17:10:04

+0

这只是一个猜测。答案在于抛出一个'ValidatorException'而忽略的捕获异常。您需要记录捕获的异常以了解原因。如果你能处理它,那就做吧。如果你不能处理它,重新抛出它作为一般/业务运行时异常或其他。 – BalusC 2011-04-13 17:30:12

+0

我想我们是彼此误解。 **正确**是你现在的问题?编辑:当**没有**单个结果时,更新的'checkCredentials()'会引发异常。你需要通过'return checkEmailExists.getResultList()。size()== 1;' – BalusC 2011-04-13 17:34:12

相关问题